bucky_objects/objects/
unique_id.rs1use crate::*;
2
3use base58::ToBase58;
4use generic_array::typenum::{marker_traits::Unsigned, U16};
5use generic_array::GenericArray;
6use std::fmt;
7
8#[derive(Clone, Eq, PartialEq)]
10pub struct UniqueId(GenericArray<u8, U16>);
11
12impl std::fmt::Debug for UniqueId {
13 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14 write!(f, "UniqueId: {}", self.0.as_slice().to_base58())
15 }
16}
17
18impl std::fmt::Display for UniqueId {
19 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20 write!(f, "{}", self.0.as_slice().to_base58())
21 }
22}
23
24impl From<GenericArray<u8, U16>> for UniqueId {
25 fn from(hash: GenericArray<u8, U16>) -> Self {
26 Self(hash)
27 }
28}
29
30impl From<UniqueId> for GenericArray<u8, U16> {
31 fn from(hash: UniqueId) -> Self {
32 hash.0
33 }
34}
35
36impl AsRef<GenericArray<u8, U16>> for UniqueId {
37 fn as_ref(&self) -> &GenericArray<u8, U16> {
38 &self.0
39 }
40}
41
42impl Default for UniqueId {
43 fn default() -> Self {
44 Self(GenericArray::default())
45 }
46}
47
48impl UniqueId {
49 pub fn as_slice(&self) -> &[u8] {
50 self.0.as_slice()
51 }
52
53 pub fn as_mut_slice(&mut self) -> &mut [u8] {
54 self.0.as_mut_slice()
55 }
56
57 pub fn clone_from_slice(slice: &[u8]) -> Self {
58 UniqueId(GenericArray::clone_from_slice(slice))
59 }
60
61 pub fn create(slice: &[u8]) -> Self {
62 let mut unique_slice = [0u8; 16];
63 let mut count = 0;
64 for c in slice {
65 unique_slice[count] = *c;
66 count += 1;
67 if count >= 16 {
68 break;
69 }
70 }
71
72 UniqueId::clone_from_slice(&unique_slice)
73 }
74
75 pub fn create_with_hash(src: &[u8]) -> Self {
77 use sha2::Digest;
78
79 let mut sha256 = sha2::Sha256::new();
80 sha256.input(src);
81 Self::create(&sha256.result())
82 }
83
84 pub fn create_with_random() -> Self {
85 let mut id = Self::default();
86 let (l, h) = id.as_mut_slice().split_at_mut(8);
87 l.copy_from_slice(&rand::random::<u64>().to_be_bytes());
88 h.copy_from_slice(&rand::random::<u64>().to_be_bytes());
89 id
90 }
91}
92
93impl RawFixedBytes for UniqueId {
94 fn raw_bytes() -> Option<usize> {
95 Some(U16::to_usize())
96 }
97}
98
99impl RawEncode for UniqueId {
100 fn raw_measure(&self, _purpose: &Option<RawEncodePurpose>) -> Result<usize, BuckyError> {
101 Ok(U16::to_usize())
102 }
103
104 fn raw_encode<'a>(
105 &self,
106 buf: &'a mut [u8],
107 _purpose: &Option<RawEncodePurpose>,
108 ) -> Result<&'a mut [u8], BuckyError> {
109 let bytes = Self::raw_bytes().unwrap();
110 if buf.len() < bytes {
111 let msg = format!(
112 "not enough buffer for encode UniqueId, except={}, got={}",
113 bytes,
114 buf.len()
115 );
116 error!("{}", msg);
117
118 return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg));
119 }
120 unsafe {
121 std::ptr::copy(self.0.as_slice().as_ptr(), buf.as_mut_ptr(), bytes);
122 }
123
124 Ok(&mut buf[bytes..])
125 }
126}
127
128impl<'de> RawDecode<'de> for UniqueId {
129 fn raw_decode(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
130 let bytes = Self::raw_bytes().unwrap();
131 if buf.len() < bytes {
132 let msg = format!(
133 "not enough buffer for decode UniqueId, except={}, got={}",
134 bytes,
135 buf.len()
136 );
137 error!("{}", msg);
138
139 return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg));
140 }
141 let mut _id = Self::default();
142 unsafe {
143 std::ptr::copy(buf.as_ptr(), _id.0.as_mut_slice().as_mut_ptr(), bytes);
144 }
145 Ok((_id, &buf[bytes..]))
146 }
147}
148
149impl ProtobufTransform<&UniqueId> for Vec<u8> {
150 fn transform(value: &UniqueId) -> BuckyResult<Self> {
151 Ok(Vec::from(value.0.as_slice()))
152 }
153}
154
155impl ProtobufTransform<Vec<u8>> for UniqueId {
156 fn transform(value: Vec<u8>) -> BuckyResult<Self> {
157 if value.len() != 32 {
158 return Err(BuckyError::new(
159 BuckyErrorCode::InvalidParam,
160 format!(
161 "try convert from vec<u8> to named unique id failed, invalid len {}",
162 value.len()
163 ),
164 ));
165 }
166 let mut id = Self::default();
167 unsafe {
168 std::ptr::copy(value.as_ptr(), id.as_mut_slice().as_mut_ptr(), value.len());
169 }
170
171 Ok(id)
172 }
173}
174
175#[cfg(test)]
176mod test {
177 use crate::*;
178
179 #[test]
180 fn test_codec() {
181 let id = UniqueId::default();
182 let len = id.raw_measure(&None).unwrap();
183 assert_eq!(len, 16);
184 let buf = id.to_vec().unwrap();
185 let (id2, left) = UniqueId::raw_decode(&buf).unwrap();
186 assert_eq!(id, id2);
187 assert!(left.is_empty());
188
189 let hash = id.raw_hash_value().unwrap();
190 println!("hash: {}", hash);
191 }
192}