1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- use std;
- use util::u128;
- use byteorder::{BigEndian,ByteOrder};
- use std::ascii::AsciiExt;
- #[derive(Debug,Copy,Clone,PartialEq,Eq,Hash)]
- pub struct SpotifyId(u128);
- #[derive(Debug,Copy,Clone,PartialEq,Eq,Hash)]
- pub struct FileId(pub [u8; 20]);
- const BASE62_DIGITS: &'static [u8] = b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
- const BASE16_DIGITS: &'static [u8] = b"0123456789abcdef";
- impl SpotifyId {
- pub fn from_base16(id: &str) -> SpotifyId {
- assert!(id.is_ascii());
- let data = id.as_bytes();
- let mut n : u128 = std::num::Zero::zero();
- for c in data {
- let d = BASE16_DIGITS.position_elem(c).unwrap() as u8;
- n = n * u128::from(16);
- n = n + u128::from(d);
- }
- SpotifyId(n)
- }
- pub fn from_base62(id: &str) -> SpotifyId {
- assert!(id.is_ascii());
- let data = id.as_bytes();
- let mut n : u128 = std::num::Zero::zero();
- for c in data {
- let d = BASE62_DIGITS.position_elem(c).unwrap() as u8;
- n = n * u128::from(62);
- n = n + u128::from(d);
- }
- SpotifyId(n)
- }
- pub fn from_raw(data: &[u8]) -> SpotifyId {
- assert_eq!(data.len(), 16);
- let high = BigEndian::read_u64(&data[0..8]);
- let low = BigEndian::read_u64(&data[8..16]);
- SpotifyId(u128::from_parts(high, low))
- }
- 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..16 {
- data[15-i] = BASE16_DIGITS[(high.wrapping_shr(4 * i as u32) & 0xF) as usize];
- }
- std::str::from_utf8(&data).unwrap().to_string()
- }
- 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);
- data
- }
- }
- impl FileId {
- pub fn to_base16(&self) -> String {
- self.0.iter()
- .map(|b| format!("{:02x}", b))
- .collect::<Vec<String>>()
- .concat()
- }
- }
|