Use HexBytes traits for base64
This commit is contained in:
parent
2621f30830
commit
af8c16dcc4
2 changed files with 106 additions and 29 deletions
13
src/b64.rs
13
src/b64.rs
|
@ -1,13 +1,16 @@
|
|||
use hex::{AsHexBytes, HexResult};
|
||||
|
||||
static B64: &'static str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+\\";
|
||||
|
||||
pub fn base64(hex: &str) -> Result<String, String> {
|
||||
let mut out = String::from("");
|
||||
let mut num_bits = 0;
|
||||
let mut acc: u32 = 0;
|
||||
for (idx, c) in hex.char_indices() {
|
||||
if let Some(c_digit) = c.to_digit(16) {
|
||||
for (idx, c) in hex.hex_bytes().enumerate() {
|
||||
match c {
|
||||
HexResult::Byte(c) => {
|
||||
// Accumulate bytes until we have 6 chunks of 4.
|
||||
acc = (acc << 4) + c_digit;
|
||||
acc = (acc << 4) + (c as u32);
|
||||
num_bits += 4;
|
||||
if idx % 6 != 5 {
|
||||
continue;
|
||||
|
@ -25,8 +28,10 @@ pub fn base64(hex: &str) -> Result<String, String> {
|
|||
}
|
||||
acc = 0;
|
||||
num_bits = 0;
|
||||
} else {
|
||||
},
|
||||
HexResult::Invalid(c) => {
|
||||
return Err(format!("Invalid input: {}", c));
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
86
src/hex.rs
86
src/hex.rs
|
@ -1,3 +1,4 @@
|
|||
use std::char;
|
||||
use std::iter;
|
||||
use std::str::Chars;
|
||||
|
||||
|
@ -6,17 +7,21 @@ pub enum HexResult {
|
|||
Invalid(char),
|
||||
}
|
||||
|
||||
pub struct HexDecoder<'a> {
|
||||
pub struct HexBytes<'a> {
|
||||
input: Chars<'a>,
|
||||
}
|
||||
|
||||
impl<'a> HexDecoder<'a> {
|
||||
fn new(input: &'a str) -> HexDecoder {
|
||||
HexDecoder { input: input.chars() }
|
||||
impl<'a> HexBytes<'a> {
|
||||
fn new(input: &'a str) -> HexBytes {
|
||||
HexBytes { input: input.chars() }
|
||||
}
|
||||
|
||||
pub fn valid(self) -> ValidHexBytes<'a> {
|
||||
ValidHexBytes::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> iter::Iterator for HexDecoder<'a> {
|
||||
impl<'a> iter::Iterator for HexBytes<'a> {
|
||||
type Item = HexResult;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
|
@ -32,14 +37,81 @@ impl<'a> iter::Iterator for HexDecoder<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ValidHexBytes --
|
||||
*/
|
||||
|
||||
pub struct ValidHexBytes<'a> {
|
||||
input: HexBytes<'a>,
|
||||
}
|
||||
|
||||
impl<'a> ValidHexBytes<'a> {
|
||||
fn new(input: HexBytes) -> ValidHexBytes {
|
||||
ValidHexBytes { input: input }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> iter::Iterator for ValidHexBytes<'a> {
|
||||
type Item = u8;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
loop {
|
||||
match self.input.next() {
|
||||
Some(hex_c) => match hex_c {
|
||||
HexResult::Byte(c) => return Some(c),
|
||||
_ => continue,
|
||||
},
|
||||
None => return None,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* HexDigest --
|
||||
*/
|
||||
|
||||
pub trait HexDigest {
|
||||
fn hex_digest(self) -> String;
|
||||
}
|
||||
|
||||
impl<'a> HexDigest for HexBytes<'a> {
|
||||
fn hex_digest(self) -> String {
|
||||
self.valid().hex_digest()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> HexDigest for ValidHexBytes<'a> {
|
||||
fn hex_digest(self) -> String {
|
||||
self.map(|x| char::from_digit(x as u32, 16).unwrap()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl HexDigest for Vec<u8> {
|
||||
fn hex_digest(self) -> String {
|
||||
self.into_iter().map(|x| char::from_digit(x as u32, 16).unwrap()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* AsHexbytes --
|
||||
*/
|
||||
|
||||
pub trait AsHexBytes<'a> {
|
||||
fn hex_bytes(&self) -> HexBytes<'a>;
|
||||
}
|
||||
|
||||
impl<'a> AsHexBytes<'a> for &'a str {
|
||||
fn hex_bytes(&self) -> HexBytes<'a> { HexBytes::new(self) }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn simple() {
|
||||
let decoder = HexDecoder::new("123");
|
||||
let collected: Vec<u8> = decoder.map(|c| match c {
|
||||
let collected: Vec<u8> = "123".hex_bytes().map(|c| match c {
|
||||
HexResult::Byte(c) => c,
|
||||
_ => panic!(),
|
||||
}).collect();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue