use rust_crypto::md5::Md5;
use rust_crypto::sha1::Sha1;
use bytes::{BufMut, BytesMut};
pub trait Digest: Send {
fn update(&mut self, data: &[u8]);
fn digest<B: BufMut>(&mut self, buf: &mut B);
fn digest_len(&self) -> usize;
fn reset(&mut self);
}
#[derive(Clone, Copy)]
pub enum DigestType {
Md5,
Sha1,
Sha,
}
pub fn with_type(t: DigestType) -> DigestVariant {
match t {
DigestType::Md5 => DigestVariant::Md5(Md5::new()),
DigestType::Sha1 | DigestType::Sha => DigestVariant::Sha1(Sha1::new()),
}
}
pub enum DigestVariant {
Md5(Md5),
Sha1(Sha1),
}
impl Digest for DigestVariant {
fn update(&mut self, data: &[u8]) {
use rust_crypto::digest::Digest;
match *self {
DigestVariant::Md5(ref mut d) => d.input(data),
DigestVariant::Sha1(ref mut d) => d.input(data),
}
}
fn digest<B: BufMut>(&mut self, buf: &mut B) {
use rust_crypto::digest::Digest;
let mut local_buf = BytesMut::with_capacity(self.digest_len());
unsafe {
local_buf.set_len(self.digest_len());
}
match *self {
DigestVariant::Md5(ref mut d) => d.result(&mut local_buf),
DigestVariant::Sha1(ref mut d) => d.result(&mut local_buf),
}
buf.put(local_buf)
}
fn digest_len(&self) -> usize {
use rust_crypto::digest::Digest;
match *self {
DigestVariant::Md5(ref d) => d.output_bytes(),
DigestVariant::Sha1(ref d) => d.output_bytes(),
}
}
fn reset(&mut self) {
use rust_crypto::digest::Digest;
match *self {
DigestVariant::Md5(ref mut d) => d.reset(),
DigestVariant::Sha1(ref mut d) => d.reset(),
}
}
}