librespot/src/util/mod.rs

132 lines
2.7 KiB
Rust
Raw Normal View History

use num::{BigUint, Integer, Zero, One};
2016-01-02 15:19:39 +00:00
use rand::{Rng, Rand};
2015-07-07 21:40:31 +00:00
use std::io;
use std::ops::{Mul, Rem, Shr};
2015-07-07 21:40:31 +00:00
use std::fs;
use std::path::Path;
use time;
2015-06-23 14:38:29 +00:00
mod int128;
mod spotify_id;
mod arcvec;
2015-06-23 17:34:48 +00:00
mod subfile;
2015-06-23 14:38:29 +00:00
pub use util::int128::u128;
pub use util::spotify_id::{SpotifyId, FileId};
pub use util::arcvec::ArcVec;
2015-06-23 17:34:48 +00:00
pub use util::subfile::Subfile;
2015-06-23 14:38:29 +00:00
#[macro_export]
macro_rules! eprintln(
($($arg:tt)*) => (
{
use std::io::Write;
writeln!(&mut ::std::io::stderr(), $($arg)* ).unwrap()
}
)
);
#[macro_export]
macro_rules! eprint(
($($arg:tt)*) => (
{
use std::io::Write;
write!(&mut ::std::io::stderr(), $($arg)* ).unwrap()
}
)
);
pub fn rand_vec<G: Rng, R: Rand>(rng: &mut G, size: usize) -> Vec<R> {
2016-03-16 00:05:05 +00:00
rng.gen_iter().take(size).collect()
2015-06-23 14:38:29 +00:00
}
2015-06-23 14:38:29 +00:00
pub mod version {
// FIXME: Unfortunately, this doesn't work when using syntex
// And for some reason, cfg-gating it doesn't work
//include!(concat!(env!("OUT_DIR"), "/version.rs"));
pub fn short_sha() -> String {
"unknown".to_owned()
}
2015-06-23 14:38:29 +00:00
pub fn version_string() -> String {
format!("librespot-{}", short_sha())
}
}
pub fn hexdump(data: &[u8]) {
for b in data.iter() {
eprint!("{:02X} ", b);
}
eprintln!("");
}
pub trait IgnoreExt {
fn ignore(self);
}
2016-01-02 15:19:39 +00:00
impl<T, E> IgnoreExt for Result<T, E> {
fn ignore(self) {
match self {
2016-01-02 15:19:39 +00:00
Ok(_) => (),
Err(_) => (),
}
}
}
pub fn now_ms() -> i64 {
let ts = time::now_utc().to_timespec();
ts.sec * 1000 + ts.nsec as i64 / 1000000
}
2015-07-07 21:40:31 +00:00
pub fn mkdir_existing(path: &Path) -> io::Result<()> {
2016-01-02 15:19:39 +00:00
fs::create_dir(path).or_else(|err| {
if err.kind() == io::ErrorKind::AlreadyExists {
Ok(())
} else {
Err(err)
2016-01-02 15:19:39 +00:00
}
})
}
pub fn powm(base: &BigUint, exp: &BigUint, modulus: &BigUint) -> BigUint {
let mut base = base.clone();
let mut exp = exp.clone();
2016-01-02 15:19:39 +00:00
let mut result: BigUint = One::one();
while !exp.is_zero() {
if exp.is_odd() {
result = result.mul(&base).rem(modulus);
}
exp = exp.shr(1);
base = (&base).mul(&base).rem(modulus);
}
2016-01-02 15:48:44 +00:00
result
2015-07-07 21:40:31 +00:00
}
pub struct StrChunks<'s>(&'s str, usize);
pub trait StrChunksExt {
2016-01-02 15:48:44 +00:00
fn chunks(&self, size: usize) -> StrChunks;
}
impl StrChunksExt for str {
2016-01-02 15:48:44 +00:00
fn chunks(&self, size: usize) -> StrChunks {
StrChunks(self, size)
}
}
2016-01-02 15:19:39 +00:00
impl<'s> Iterator for StrChunks<'s> {
type Item = &'s str;
fn next(&mut self) -> Option<&'s str> {
let &mut StrChunks(data, size) = self;
if data.is_empty() {
None
} else {
let ret = Some(&data[..size]);
self.0 = &data[size..];
ret
}
}
}