hydrate_base/
asset_id.rs

1use serde::{de, ser};
2use serde::{Deserialize, Serialize};
3use std::fmt;
4use std::str::FromStr;
5use uuid::Uuid;
6
7/// ID for a user-edited piece of data. It may have import data associated with it. Assets can be
8/// thought of as a list of properties that follow a particular schema.
9#[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Default)]
10pub struct AssetId(pub Uuid);
11impl AssetId {
12    pub const fn null() -> Self {
13        AssetId(Uuid::nil())
14    }
15
16    pub fn parse_str(input: &str) -> Result<Self, uuid::Error> {
17        Ok(AssetId(Uuid::parse_str(input)?))
18    }
19
20    pub fn is_null(&self) -> bool {
21        self.0.is_nil()
22    }
23
24    pub fn from_uuid(uuid: Uuid) -> Self {
25        AssetId(uuid)
26    }
27
28    pub fn as_uuid(&self) -> Uuid {
29        self.0
30    }
31
32    pub fn from_u128(u: u128) -> Self {
33        Self(Uuid::from_u128(u))
34    }
35
36    pub fn as_u128(&self) -> u128 {
37        self.0.as_u128()
38    }
39
40    pub fn from_bytes(bytes: uuid::Bytes) -> Self {
41        AssetId(Uuid::from_bytes(bytes))
42    }
43
44    pub fn as_bytes(&self) -> &uuid::Bytes {
45        self.0.as_bytes()
46    }
47}
48
49impl fmt::Debug for AssetId {
50    fn fmt(
51        &self,
52        f: &mut fmt::Formatter<'_>,
53    ) -> fmt::Result {
54        f.debug_tuple("AssetId").field(&self.0).finish()
55    }
56}
57
58impl fmt::Display for AssetId {
59    fn fmt(
60        &self,
61        f: &mut fmt::Formatter<'_>,
62    ) -> fmt::Result {
63        self.0.fmt(f)
64    }
65}
66
67impl Serialize for AssetId {
68    fn serialize<S: ser::Serializer>(
69        &self,
70        serializer: S,
71    ) -> Result<S::Ok, S::Error> {
72        if serializer.is_human_readable() {
73            serializer.serialize_str(&self.to_string())
74        } else {
75            self.0.serialize(serializer)
76        }
77    }
78}
79
80struct AssetIdVisitor;
81
82impl<'a> de::Visitor<'a> for AssetIdVisitor {
83    type Value = AssetId;
84
85    fn expecting(
86        &self,
87        fmt: &mut fmt::Formatter<'_>,
88    ) -> fmt::Result {
89        write!(fmt, "a UUID-formatted string")
90    }
91
92    fn visit_str<E: de::Error>(
93        self,
94        s: &str,
95    ) -> Result<Self::Value, E> {
96        Uuid::from_str(s)
97            .map(|id| AssetId(id))
98            .map_err(|_| de::Error::invalid_value(de::Unexpected::Str(s), &self))
99    }
100}
101
102impl<'de> Deserialize<'de> for AssetId {
103    fn deserialize<D: de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
104        if deserializer.is_human_readable() {
105            deserializer.deserialize_string(AssetIdVisitor)
106        } else {
107            Ok(AssetId(Uuid::deserialize(deserializer)?))
108        }
109    }
110}