aboutsummaryrefslogtreecommitdiff
path: root/src/data.rs
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2020-04-07 18:10:20 +0200
committerAlex Auvolat <alex@adnab.me>2020-04-07 18:10:20 +0200
commit90cdffb425c6222f4234db54a16c079d8c058724 (patch)
tree2a836af28b5bce3969560fa4f45973b8392629c2 /src/data.rs
parent82b7fcd280d416aabc4f94a99a17c8d9e99888be (diff)
downloadgarage-90cdffb425c6222f4234db54a16c079d8c058724.tar.gz
garage-90cdffb425c6222f4234db54a16c079d8c058724.zip
custom data type for hashes and identifiers
Diffstat (limited to 'src/data.rs')
-rw-r--r--src/data.rs71
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