| 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()    }}
 |