cyfs_base/objects/
unique_id.rs

1use crate::*;
2
3use generic_array::typenum::{marker_traits::Unsigned, U16};
4use generic_array::GenericArray;
5use std::fmt;
6use base58::ToBase58;
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
85impl RawFixedBytes for UniqueId {
86    fn raw_bytes() -> Option<usize> {
87        Some(U16::to_usize())
88    }
89}
90
91impl RawEncode for UniqueId {
92    fn raw_measure(&self, _purpose: &Option<RawEncodePurpose>) -> Result<usize, BuckyError> {
93        Ok(U16::to_usize())
94    }
95
96    fn raw_encode<'a>(
97        &self,
98        buf: &'a mut [u8],
99        _purpose: &Option<RawEncodePurpose>,
100    ) -> Result<&'a mut [u8], BuckyError> {
101        let bytes = Self::raw_bytes().unwrap();
102        if buf.len() < bytes {
103            let msg = format!(
104                "not enough buffer for encode UniqueId, except={}, got={}",
105                bytes,
106                buf.len()
107            );
108            error!("{}", msg);
109
110            return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg));
111        }
112        unsafe {
113            std::ptr::copy(self.0.as_slice().as_ptr(), buf.as_mut_ptr(), bytes);
114        }
115
116        Ok(&mut buf[bytes..])
117    }
118}
119
120impl<'de> RawDecode<'de> for UniqueId {
121    fn raw_decode(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
122        let bytes = Self::raw_bytes().unwrap();
123        if buf.len() < bytes {
124            let msg = format!(
125                "not enough buffer for decode UniqueId, except={}, got={}",
126                bytes,
127                buf.len()
128            );
129            error!("{}", msg);
130
131            return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg));
132        }
133        let mut _id = Self::default();
134        unsafe {
135            std::ptr::copy(buf.as_ptr(), _id.0.as_mut_slice().as_mut_ptr(), bytes);
136        }
137        Ok((_id, &buf[bytes..]))
138    }
139}
140
141impl ProtobufTransform<&UniqueId> for Vec<u8> {
142    fn transform(value: &UniqueId) -> BuckyResult<Self> {
143        Ok(Vec::from(value.0.as_slice()))
144    }
145}
146
147impl ProtobufTransform<Vec<u8>> for UniqueId {
148    fn transform(value: Vec<u8>) -> BuckyResult<Self> {
149        if value.len() != 32 {
150            return Err(BuckyError::new(
151                BuckyErrorCode::InvalidParam,
152                format!(
153                    "try convert from vec<u8> to named unique id failed, invalid len {}",
154                    value.len()
155                ),
156            ));
157        }
158        let mut id = Self::default();
159        unsafe {
160            std::ptr::copy(value.as_ptr(), id.as_mut_slice().as_mut_ptr(), value.len());
161        }
162
163        Ok(id)
164    }
165}
166
167#[cfg(test)]
168mod test {
169    use crate::*;
170
171    #[test]
172    fn test_codec() {
173        let id = UniqueId::default();
174        let len = id.raw_measure(&None).unwrap();
175        assert_eq!(len, 16);
176        let buf = id.to_vec().unwrap();
177        let (id2, left) = UniqueId::raw_decode(&buf).unwrap();
178        assert_eq!(id, id2);
179        assert!(left.is_empty());
180
181        let hash = id.raw_hash_value().unwrap();
182        println!("hash: {}", hash);
183    }
184}