TextureSync/server/texture-sync-server/src/model/sha256.rs

89 lines
2.4 KiB
Rust

use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
pub struct Sha256(#[serde(serialize_with = "as_hex", deserialize_with = "from_hex")] pub [u8; 32]);
fn as_hex<S>(hash: &[u8; 32], serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
use std::fmt::*;
let mut hex_string = String::new();
for digit in hash {
write!(hex_string, "{:02X}", digit).unwrap();
}
serializer.serialize_str(&hex_string)
}
fn from_hex<'de, D>(deserializer: D) -> Result<[u8; 32], D::Error>
where
D: Deserializer<'de>,
{
use serde::de::Error;
fn hex2bytes(s: &str) -> Option<[u8; 32]> {
if s.len() != 32 * 2 {
return None; // String has wrong length
}
let mut out = [0u8; 32];
for (i, byte) in out.iter_mut().enumerate() {
let string_index = i * 2;
*byte = u8::from_str_radix(&s[string_index..=string_index + 1], 16).ok()?;
}
return Some(out);
}
String::deserialize(deserializer).and_then(|string| {
hex2bytes(&string).ok_or_else(|| Error::custom("Invalid HEX String!".to_string()))
})
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json;
const HASH_BYTES: [u8; 32] = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31,
];
const HASH_STRING: &'static str =
r#""000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F""#;
#[test]
fn serialize() {
let hash = serde_json::to_string_pretty(&Sha256(HASH_BYTES)).unwrap();
assert_eq!(&hash, HASH_STRING);
}
#[test]
fn deserialize() {
let hash: Sha256 = serde_json::from_str(HASH_STRING).unwrap();
assert_eq!(hash, Sha256(HASH_BYTES))
}
#[test]
fn fail_deserialize() {
// too short.
assert_eq!(
serde_json::from_str::<'_, Sha256>(r#""0102013""#).is_err(),
true
);
// wrong radix
assert_eq!(
serde_json::from_str::<'_, Sha256>(r#""Hallo Welt""#).is_err(),
true
);
// too long.
assert_eq!(
serde_json::from_str::<'_, Sha256>( r#""000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F""#).is_err(),
true
);
}
}