use std::fmt::{self, Write};
static STANDARD_CHARS: &'static[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
abcdefghijklmnopqrstuvwxyz\
0123456789+/";
pub struct Base64<'a>(pub &'a [u8]);
impl<'a> fmt::Display for Base64<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let len = self.0.len();
let mod_len = len % 3;
let mut s_in = self.0[..len - mod_len].iter().map(|&x| x as u32);
let enc = |val| STANDARD_CHARS[val as usize];
let mut write = |val| fmt.write_char(val as char).unwrap();
while let (Some(first), Some(second), Some(third)) =
(s_in.next(), s_in.next(), s_in.next()) {
let n = first << 16 | second << 8 | third;
write(enc((n >> 18) & 63));
write(enc((n >> 12) & 63));
write(enc((n >> 6 ) & 63));
write(enc((n >> 0 ) & 63));
}
match mod_len {
0 => {},
1 => {
let n = (self.0[len-1] as u32) << 16;
write(enc((n >> 18) & 63));
write(enc((n >> 12) & 63));
write(b'=');
write(b'=');
}
2 => {
let n = (self.0[len-2] as u32) << 16 |
(self.0[len-1] as u32) << 8;
write(enc((n >> 18) & 63));
write(enc((n >> 12) & 63));
write(enc((n >> 6 ) & 63));
write(b'=');
}
_ => panic!("Algebra is broken, please alert the math police")
}
Ok(())
}
}