mod.rs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. use num::{BigUint, Integer, Zero, One};
  2. use rand::{Rng, Rand};
  3. use std::io;
  4. use std::ops::{Mul, Rem, Shr};
  5. use std::fs;
  6. use std::path::Path;
  7. use time;
  8. mod int128;
  9. mod spotify_id;
  10. mod arcvec;
  11. mod subfile;
  12. pub use util::int128::u128;
  13. pub use util::spotify_id::{SpotifyId, FileId};
  14. pub use util::arcvec::ArcVec;
  15. pub use util::subfile::Subfile;
  16. #[macro_export]
  17. macro_rules! eprintln(
  18. ($($arg:tt)*) => (
  19. {
  20. use std::io::Write;
  21. writeln!(&mut ::std::io::stderr(), $($arg)* ).unwrap()
  22. }
  23. )
  24. );
  25. #[macro_export]
  26. macro_rules! eprint(
  27. ($($arg:tt)*) => (
  28. {
  29. use std::io::Write;
  30. write!(&mut ::std::io::stderr(), $($arg)* ).unwrap()
  31. }
  32. )
  33. );
  34. pub fn rand_vec<G: Rng, R: Rand>(rng: &mut G, size: usize) -> Vec<R> {
  35. let mut vec = Vec::with_capacity(size);
  36. for _ in 0..size {
  37. vec.push(R::rand(rng));
  38. }
  39. vec
  40. }
  41. pub mod version {
  42. // FIXME: Unfortunately, this doesn't work when using syntex
  43. // And for some reason, cfg-gating it doesn't work
  44. //include!(concat!(env!("OUT_DIR"), "/version.rs"));
  45. pub fn short_sha() -> String {
  46. "unknown".to_owned()
  47. }
  48. pub fn version_string() -> String {
  49. format!("librespot-{}", short_sha())
  50. }
  51. }
  52. pub fn hexdump(data: &[u8]) {
  53. for b in data.iter() {
  54. eprint!("{:02X} ", b);
  55. }
  56. eprintln!("");
  57. }
  58. pub trait IgnoreExt {
  59. fn ignore(self);
  60. }
  61. impl<T, E> IgnoreExt for Result<T, E> {
  62. fn ignore(self) {
  63. match self {
  64. Ok(_) => (),
  65. Err(_) => (),
  66. }
  67. }
  68. }
  69. pub fn now_ms() -> i64 {
  70. let ts = time::now_utc().to_timespec();
  71. ts.sec * 1000 + ts.nsec as i64 / 1000000
  72. }
  73. pub fn mkdir_existing(path: &Path) -> io::Result<()> {
  74. fs::create_dir(path).or_else(|err| {
  75. if err.kind() == io::ErrorKind::AlreadyExists {
  76. Ok(())
  77. } else {
  78. Err(err)
  79. }
  80. })
  81. }
  82. pub fn powm(base: &BigUint, exp: &BigUint, modulus: &BigUint) -> BigUint {
  83. let mut base = base.clone();
  84. let mut exp = exp.clone();
  85. let mut result: BigUint = One::one();
  86. while !exp.is_zero() {
  87. if exp.is_odd() {
  88. result = result.mul(&base).rem(modulus);
  89. }
  90. exp = exp.shr(1);
  91. base = (&base).mul(&base).rem(modulus);
  92. }
  93. result
  94. }
  95. pub struct StrChunks<'s>(&'s str, usize);
  96. pub trait StrChunksExt {
  97. fn chunks(&self, size: usize) -> StrChunks;
  98. }
  99. impl StrChunksExt for str {
  100. fn chunks(&self, size: usize) -> StrChunks {
  101. StrChunks(self, size)
  102. }
  103. }
  104. impl<'s> Iterator for StrChunks<'s> {
  105. type Item = &'s str;
  106. fn next(&mut self) -> Option<&'s str> {
  107. let &mut StrChunks(data, size) = self;
  108. if data.is_empty() {
  109. None
  110. } else {
  111. let ret = Some(&data[..size]);
  112. self.0 = &data[size..];
  113. ret
  114. }
  115. }
  116. }