1use std::fmt;
21use std::ops;
22
23use hex::{FromHex, FromHexError, ToHex};
24use serde::de::{self, Deserialize, Deserializer, Visitor};
25use serde::ser::{self, Serialize, Serializer};
26
27#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Default)]
29pub struct Oid([u8; 20]);
30
31impl Oid {
32 pub fn from_hex(s: &str) -> Result<Self, ()> {
33 Ok(Oid(<[u8; 20]>::from_hex(s).map_err(|_| ())?))
34 }
35
36 pub fn empty_tree() -> Oid {
40 Oid([
41 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, 0xe5,
42 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04,
43 ])
44 }
45
46 pub fn zero() -> Oid {
48 Oid([
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 ])
52 }
53}
54
55impl fmt::UpperHex for Oid {
56 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
57 self.write_hex_upper(f)
58 }
59}
60
61impl fmt::LowerHex for Oid {
62 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63 self.write_hex(f)
64 }
65}
66
67impl fmt::Display for Oid {
68 #[inline]
69 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70 <Self as fmt::LowerHex>::fmt(self, f)
71 }
72}
73
74impl fmt::Debug for Oid {
75 #[inline]
76 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
77 <Self as fmt::Display>::fmt(self, f)
78 }
79}
80
81impl ops::Deref for Oid {
82 type Target = [u8; 20];
83
84 fn deref(&self) -> &Self::Target {
85 &self.0
86 }
87}
88
89impl Serialize for Oid {
90 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
91 where
92 S: Serializer,
93 {
94 if serializer.is_human_readable() {
95 let mut hex = String::new();
97 self.0
98 .as_ref()
99 .write_hex(&mut hex)
100 .map_err(ser::Error::custom)?;
101 serializer.serialize_str(&hex)
102 } else {
103 serializer.serialize_bytes(self.0.as_ref())
105 }
106 }
107}
108
109impl<'de> Deserialize<'de> for Oid {
110 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
111 where
112 D: Deserializer<'de>,
113 {
114 struct OidVisitor;
115
116 impl<'de> Visitor<'de> for OidVisitor {
117 type Value = Oid;
118
119 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
120 write!(f, "hex string or 20 bytes")
121 }
122
123 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
124 where
125 E: de::Error,
126 {
127 let v = <[u8; 20]>::from_hex(v).map_err(|e| match e {
128 FromHexError::InvalidHexCharacter { c, .. } => {
129 E::invalid_value(
130 de::Unexpected::Char(c),
131 &"string with only hexadecimal characters",
132 )
133 }
134 FromHexError::InvalidStringLength => E::invalid_length(
135 v.len(),
136 &"hex string with a valid length",
137 ),
138 FromHexError::OddLength => E::invalid_length(
139 v.len(),
140 &"hex string with an even length",
141 ),
142 })?;
143
144 Ok(Oid(v))
145 }
146
147 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
148 where
149 E: de::Error,
150 {
151 if v.len() != 20 {
152 return Err(E::invalid_length(v.len(), &"20 bytes"));
153 }
154
155 let mut inner = <[u8; 20]>::default();
156 inner.copy_from_slice(v);
157
158 Ok(Oid(inner))
159 }
160 }
161
162 if deserializer.is_human_readable() {
163 deserializer.deserialize_str(OidVisitor)
164 } else {
165 deserializer.deserialize_bytes(OidVisitor)
166 }
167 }
168}