diff --git a/Cargo.lock b/Cargo.lock index a325f759..7671881d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -121,6 +121,17 @@ name = "error-chain" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "extprim" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fuchsia-zircon" version = "0.3.3" @@ -374,6 +385,7 @@ dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "extprim 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.11.14 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -660,6 +672,16 @@ dependencies = [ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "redox_syscall" version = "0.1.37" @@ -724,6 +746,14 @@ name = "rustc-serialize" version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rustc_version" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "safemem" version = "0.2.0" @@ -734,11 +764,32 @@ name = "scoped-tls" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "serde" version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "serde" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "serde_codegen_internals" version = "0.14.2" @@ -757,6 +808,25 @@ dependencies = [ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "serde_derive" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_derive_internals" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "serde_json" version = "0.9.10" @@ -1118,6 +1188,7 @@ dependencies = [ "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" "checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" "checksum error-chain 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e92ecf0a508c8e074c0e6fa8fe0fa38414848ad4dfc4db6f74c5e9753330b248" +"checksum extprim 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb09b6eb24a48a5c57729e4a60980bf538b3662c3bcec04b6c7908d7a0f3d9b9" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "118b49cac82e04121117cbd3121ede3147e885627d82c4546b87c702debb90c1" @@ -1167,6 +1238,7 @@ dependencies = [ "checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1" +"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" "checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" "checksum regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "744554e01ccbd98fff8c457c3b092cd67af62a555a43bfe97ae8a0451f7799fa" "checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" @@ -1175,11 +1247,17 @@ dependencies = [ "checksum rust-crypto 0.2.36 (git+https://github.com/awmath/rust-crypto.git?branch=avx2)" = "" "checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" +"checksum rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a54aa04a10c68c1c4eacb4337fd883b435997ede17a9385784b990777686b09a" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" +"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)" = "34b623917345a631dc9608d5194cc206b3fe6c3554cd1c75b937e55e285254af" +"checksum serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "db99f3919e20faa51bb2996057f5031d8685019b5a06139b1ce761da671b8526" "checksum serde_codegen_internals 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bc888bd283bd2420b16ad0d860e35ad8acb21941180a83a189bb2046f9d00400" "checksum serde_derive 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)" = "978fd866f4d4872084a81ccc35e275158351d3b9fe620074e7d7504b816b74ba" +"checksum serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "f4ba7591cfe93755e89eeecdbcc668885624829b020050e6aec99c2a03bd3fd0" +"checksum serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e03f1c9530c3fb0a0a5c9b826bdd9246a5921ae995d75f512ac917fc4dd55b5" "checksum serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ad8bcf487be7d2e15d3d543f04312de991d631cfe1b43ea0ade69e6a8a5b16a1" "checksum shannon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7ea5b41c9427b56caa7b808cb548a04fb50bb5b9e98590b53f28064ff4174561" "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" diff --git a/core/Cargo.toml b/core/Cargo.toml index f563f315..b2a68ef8 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -12,6 +12,7 @@ base64 = "0.5.0" byteorder = "1.0" bytes = "0.4" error-chain = { version = "0.9.0", default_features = false } +extprim = "1.5.1" futures = "0.1.8" hyper = "0.11.2" lazy_static = "0.2.0" diff --git a/core/src/lib.rs b/core/src/lib.rs index 3c9be131..2d011385 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -15,6 +15,7 @@ extern crate base64; extern crate byteorder; extern crate bytes; extern crate crypto; +extern crate extprim; extern crate hyper; extern crate num_bigint; extern crate num_integer; diff --git a/core/src/spotify_id.rs b/core/src/spotify_id.rs index 314708e8..0bbe7854 100644 --- a/core/src/spotify_id.rs +++ b/core/src/spotify_id.rs @@ -1,7 +1,7 @@ use byteorder::{BigEndian, ByteOrder}; use std; use std::fmt; -use util::u128; +use extprim::u128::u128; // Unneeded since 1.21 #[allow(unused_imports)] use std::ascii::AsciiExt; @@ -23,10 +23,10 @@ impl SpotifyId { for c in data { let d = match BASE16_DIGITS.iter().position(|e| e == c) { None => return Err(SpotifyIdError), - Some(x) => x as u8, + Some(x) => x as u64, }; - n = n * u128::from(16); - n = n + u128::from(d); + n = n * u128::new(16); + n = n + u128::new(d); } Ok(SpotifyId(n)) @@ -39,10 +39,10 @@ impl SpotifyId { for c in data { let d = match BASE62_DIGITS.iter().position(|e| e == c) { None => return Err(SpotifyIdError), - Some(x) => x as u8, + Some(x) => x as u64, }; - n = n * u128::from(62); - n = n + u128::from(d); + n = n * u128::new(62); + n = n + u128::new(d); } Ok(SpotifyId(n)) @@ -61,14 +61,23 @@ impl SpotifyId { pub fn to_base16(&self) -> String { let &SpotifyId(ref n) = self; - let (high, low) = n.parts(); let mut data = [0u8; 32]; - for i in 0..16 { - data[31 - i] = BASE16_DIGITS[(low.wrapping_shr(4 * i as u32) & 0xF) as usize]; + for i in 0..32 { + data[31 - i] = BASE16_DIGITS[(n.wrapping_shr(4 * i as u32).low64() & 0xF) as usize]; } - for i in 0..16 { - data[15 - i] = BASE16_DIGITS[(high.wrapping_shr(4 * i as u32) & 0xF) as usize]; + + std::str::from_utf8(&data).unwrap().to_owned() + } + + pub fn to_base62(&self) -> String { + let &SpotifyId(mut n) = self; + + let mut data = [0u8; 22]; + let sixty_two = u128::new(62); + for i in 0..22 { + data[21-i] = BASE62_DIGITS[(n % sixty_two).low64() as usize]; + n /= sixty_two; } std::str::from_utf8(&data).unwrap().to_owned() @@ -76,12 +85,11 @@ impl SpotifyId { pub fn to_raw(&self) -> [u8; 16] { let &SpotifyId(ref n) = self; - let (high, low) = n.parts(); let mut data = [0u8; 16]; - BigEndian::write_u64(&mut data[0..8], high); - BigEndian::write_u64(&mut data[8..16], low); + BigEndian::write_u64(&mut data[0..8], n.high64()); + BigEndian::write_u64(&mut data[8..16], n.low64()); data } diff --git a/core/src/util/int128.rs b/core/src/util/int128.rs deleted file mode 100644 index 648c5aae..00000000 --- a/core/src/util/int128.rs +++ /dev/null @@ -1,95 +0,0 @@ -use std; - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -#[allow(non_camel_case_types)] -pub(crate) struct u128 { - high: u64, - low: u64, -} - -impl u128 { - pub fn zero() -> u128 { - u128::from_parts(0, 0) - } - - pub fn from_parts(high: u64, low: u64) -> u128 { - u128 { - high: high, - low: low, - } - } - - pub fn parts(&self) -> (u64, u64) { - (self.high, self.low) - } -} - -impl std::ops::Add for u128 { - type Output = u128; - fn add(self, rhs: u128) -> u128 { - let low = self.low + rhs.low; - let high = self.high + rhs.high + if low < self.low { 1 } else { 0 }; - - u128::from_parts(high, low) - } -} - -impl<'a> std::ops::Add<&'a u128> for u128 { - type Output = u128; - fn add(self, rhs: &'a u128) -> u128 { - let low = self.low + rhs.low; - let high = self.high + rhs.high + if low < self.low { 1 } else { 0 }; - - u128::from_parts(high, low) - } -} - -impl std::convert::From for u128 { - fn from(n: u8) -> u128 { - u128::from_parts(0, n as u64) - } -} - -impl std::ops::Mul for u128 { - type Output = u128; - - fn mul(self, rhs: u128) -> u128 { - let top: [u64; 4] = [ - self.high >> 32, - self.high & 0xFFFFFFFF, - self.low >> 32, - self.low & 0xFFFFFFFF, - ]; - - let bottom: [u64; 4] = [ - rhs.high >> 32, - rhs.high & 0xFFFFFFFF, - rhs.low >> 32, - rhs.low & 0xFFFFFFFF, - ]; - - let mut rows = [u128::zero(); 16]; - for i in 0..4 { - for j in 0..4 { - let shift = i + j; - let product = top[3 - i] * bottom[3 - j]; - let (high, low) = match shift { - 0 => (0, product), - 1 => (product >> 32, product << 32), - 2 => (product, 0), - 3 => (product << 32, 0), - _ => { - if product == 0 { - (0, 0) - } else { - panic!("Overflow on mul {:?} {:?} ({} {})", self, rhs, i, j) - } - } - }; - rows[j * 4 + i] = u128::from_parts(high, low); - } - } - - rows.iter().fold(u128::zero(), std::ops::Add::add) - } -} diff --git a/core/src/util/mod.rs b/core/src/util/mod.rs index a41638bc..7c932306 100644 --- a/core/src/util/mod.rs +++ b/core/src/util/mod.rs @@ -5,10 +5,6 @@ use rand::{Rand, Rng}; use std::mem; use std::ops::{Mul, Rem, Shr}; -mod int128; - -pub(crate) use util::int128::u128; - pub fn rand_vec(rng: &mut G, size: usize) -> Vec { rng.gen_iter().take(size).collect() } diff --git a/playback/src/player.rs b/playback/src/player.rs index 059c8069..0d73de7d 100644 --- a/playback/src/player.rs +++ b/playback/src/player.rs @@ -533,7 +533,7 @@ impl PlayerInternal { fn load_track(&self, track_id: SpotifyId, position: i64) -> Option<(Decoder, f32)> { let track = Track::get(&self.session, track_id).wait().unwrap(); - info!("Loading track \"{}\"", track.name); + info!("Loading track \"{}\" with Spotify URI \"{}\"", track.name, track_id.to_base62()); let track = match self.find_available_alternative(&track) { Some(track) => track,