diff options
author | Alex Auvolat <alex@adnab.me> | 2020-04-07 18:10:20 +0200 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2020-04-07 18:10:20 +0200 |
commit | 90cdffb425c6222f4234db54a16c079d8c058724 (patch) | |
tree | 2a836af28b5bce3969560fa4f45973b8392629c2 /src/data.rs | |
parent | 82b7fcd280d416aabc4f94a99a17c8d9e99888be (diff) | |
download | garage-90cdffb425c6222f4234db54a16c079d8c058724.tar.gz garage-90cdffb425c6222f4234db54a16c079d8c058724.zip |
custom data type for hashes and identifiers
Diffstat (limited to 'src/data.rs')
-rw-r--r-- | src/data.rs | 71 |
1 files changed, 68 insertions, 3 deletions
diff --git a/src/data.rs b/src/data.rs index c649b289..f54c4cc1 100644 --- a/src/data.rs +++ b/src/data.rs @@ -1,8 +1,73 @@ +use std::fmt; use std::collections::HashMap; -use serde::{Serialize, Deserialize}; +use serde::{Serializer, Deserializer, Serialize, Deserialize}; +use serde::de::{self, Visitor}; -pub type UUID = [u8; 32]; -pub type Hash = [u8; 32]; +#[derive(Default, PartialOrd, Ord, Clone, Hash, PartialEq)] +pub struct FixedBytes32([u8; 32]); + +impl From<[u8; 32]> for FixedBytes32 { + fn from(x: [u8; 32]) -> FixedBytes32 { + FixedBytes32(x) + } +} + +impl std::convert::AsRef<[u8]> for FixedBytes32 { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + +impl Eq for FixedBytes32 {} + +impl fmt::Debug for FixedBytes32 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", hex::encode(self.0)) + } +} + +struct FixedBytes32Visitor; +impl<'de> Visitor<'de> for FixedBytes32Visitor { + type Value = FixedBytes32; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a byte slice of size 32") + } + + fn visit_bytes<E: de::Error>(self, value: &[u8]) -> Result<Self::Value, E> { + if value.len() == 32 { + let mut res = [0u8; 32]; + res.copy_from_slice(value); + Ok(res.into()) + } else { + Err(E::custom(format!("Invalid byte string length {}, expected 32", value.len()))) + } + } +} + +impl<'de> Deserialize<'de> for FixedBytes32 { + fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<FixedBytes32, D::Error> { + deserializer.deserialize_bytes(FixedBytes32Visitor) + } +} + +impl Serialize for FixedBytes32 { + fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { + serializer.serialize_bytes(&self.0[..]) + } +} + +impl FixedBytes32 { + pub fn as_slice(&self) -> &[u8] { + &self.0[..] + } + pub fn as_slice_mut(&mut self) -> &mut [u8] { + &mut self.0[..] + } +} + +pub type UUID = FixedBytes32; +pub type Hash = FixedBytes32; // Network management |