// use std::fmt::{Debug, Display, Formatter}; // use serde::{Deserialize, Deserializer}; // use serde::de::{Error, Visitor}; // use hex::{FromHex, FromHexError, ToHex}; // use sha1_smol::Sha1; // // // sha1 digests are 20 bytes long // pub use sha1_smol::DIGEST_LENGTH; // pub type Sha1DigestBytes = [u8; DIGEST_LENGTH]; // // #[derive(PartialEq, Eq, PartialOrd, Ord, Clone)] // pub struct Sha1Digest(pub Sha1DigestBytes); // // impl Debug for Sha1Digest { // fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { // write!(f, "Sha1Digest {{{}}}", self.0.encode_hex::()) // } // } // // impl Display for Sha1Digest { // fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { // f.write_str(&self.0.encode_hex::()) // } // } // // impl Sha1Digest { // pub fn from_hex(s: &str) -> Result { // // } // use sha1_smol::{Digest, Sha1}; pub fn verify_sha1(expect: Digest, s: &str) -> Result<(), Digest> { let dig = Sha1::from(s).digest(); if dig == expect { return Ok(()); } Err(dig) } // // pub fn as_hex(&self) -> String { // // allocate the string with capacity first so we only do one heap alloc // let mut s: String = String::with_capacity(2 * self.0.len()); // self.0.iter().for_each(|b| s.push_str(&format!("{:02x}", b))); // s // } // } // // struct Sha1DigestVisitor; // // impl <'a> Visitor<'a> for Sha1DigestVisitor { // type Value = Sha1Digest; // // fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { // write!(formatter, "a valid SHA-1 digest (40-character hex string)") // } // // fn visit_str(self, v: &str) -> Result // where // E: Error, // { // Sha1DigestBytes::from_hex(v).map_err(|e| E::custom(e)).map(Sha1Digest) // } // } // // impl<'a> Deserialize<'a> for Sha1Digest { // fn deserialize(deserializer: D) -> Result // where // D: Deserializer<'a>, // { // deserializer.deserialize_any(Sha1DigestVisitor) // } // }