bucky_objects/objects/
unique_id.rs

1use crate::*;
2
3use base58::ToBase58;
4use generic_array::typenum::{marker_traits::Unsigned, U16};
5use generic_array::GenericArray;
6use std::fmt;
7
8// unique id in const info
9#[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    // 从源计算hash256,然后取前16bytes做uniqueId
76    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}