cyfs_base/objects/
named_object_id.rs

1use crate::*;
2
3use std::cmp::Ordering;
4use std::convert::TryFrom;
5use std::fmt;
6use std::fmt::Formatter;
7use std::hash::{Hash, Hasher};
8use std::marker::PhantomData;
9use std::str::FromStr;
10
11/// 强类型命名对象Id
12/// ===
13/// 手工实现PartialEq、Eq、PartialOrd、Ord,附加的类型上并不需要实现这四个Trait
14/// 转发这四个Trait的实现给内部的ObjectId
15#[derive(Copy, Clone)]
16pub struct NamedObjectId<T: ObjectType>(ObjectId, Option<PhantomData<T>>);
17
18impl<T: ObjectType> PartialEq for NamedObjectId<T> {
19    fn eq(&self, other: &Self) -> bool {
20        self.0 == other.0
21    }
22}
23
24impl<T: ObjectType> PartialEq<ObjectId> for NamedObjectId<T> {
25    fn eq(&self, other: &ObjectId) -> bool {
26        self.0 == *other
27    }
28}
29
30impl<T: ObjectType> PartialEq<NamedObjectId<T>> for ObjectId {
31    fn eq(&self, other: &NamedObjectId<T>) -> bool {
32        *self == other.0
33    }
34}
35
36impl<T: ObjectType> Eq for NamedObjectId<T> {}
37
38impl<T: ObjectType> PartialOrd for NamedObjectId<T> {
39    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
40        self.0.partial_cmp(&other.0)
41    }
42}
43
44impl<T: ObjectType> Ord for NamedObjectId<T> {
45    fn cmp(&self, other: &Self) -> Ordering {
46        self.0.cmp(&other.0)
47    }
48}
49
50impl<T: ObjectType> NamedObjectId<T> {
51    pub fn object_id(&self) -> &ObjectId {
52        &self.0
53    }
54    pub fn object_id_mut(&mut self) -> &mut ObjectId {
55        &mut self.0
56    }
57}
58
59impl<T: ObjectType> std::convert::Into<ObjectId> for NamedObjectId<T> {
60    fn into(self) -> ObjectId {
61        self.0
62    }
63}
64
65impl<T: ObjectType> Default for NamedObjectId<T> {
66    fn default() -> Self {
67        let mut id = ObjectId::default();
68        let hash_value = id.as_mut_slice();
69
70        if !T::is_standard_object() {
71            // 用户类型
72            //4个可用flag
73            let type_code = if T::is_dec_app_object() {
74                //这是一个dec app 对象
75                0b_110000
76            } else {
77                //这是一个core 对象
78                0b_100000
79            };
80
81            // 前 6 bit 写入类型信息
82            hash_value[0] = type_code << 2;
83        } else {
84            // 标准类型
85            let type_code = T::obj_type() as u8;
86
87            hash_value[0] = 0b_01000000 | type_code << 4 >> 2;
88        };
89
90        let id = ObjectId::clone_from_slice(&hash_value).unwrap();
91
92        Self(id, None)
93    }
94}
95
96impl<T: ObjectType> std::fmt::Display for NamedObjectId<T> {
97    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
98        write!(f, "{}", self.0.to_string())
99    }
100}
101
102impl<T: ObjectType> std::fmt::Debug for NamedObjectId<T> {
103    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104        write!(f, "{}", self.0.to_string())
105        /*
106        write!(
107            f,
108            "(obj_id: {:?}, obj_type_code: {:?}, obj_type:{})",
109            self.0.as_slice().to_base58(),
110            T::obj_type_code(),
111            T::obj_type(),
112        )
113        */
114    }
115}
116
117impl<T: ObjectType> ProtobufTransform<Vec<u8>> for NamedObjectId<T> {
118    fn transform(value: Vec<u8>) -> BuckyResult<Self> {
119        Ok(Self(ObjectId::transform(value)?, None))
120    }
121}
122
123impl<T: ObjectType> ProtobufTransform<&NamedObjectId<T>> for Vec<u8> {
124    fn transform(value: &NamedObjectId<T>) -> BuckyResult<Self> {
125        Ok(ProtobufTransform::transform(&value.0)?)
126    }
127}
128
129impl<T: ObjectType> Hash for NamedObjectId<T> {
130    fn hash<H: Hasher>(&self, state: &mut H) {
131        state.write(self.0.as_slice());
132    }
133}
134
135impl<T: ObjectType> FromStr for NamedObjectId<T> {
136    type Err = BuckyError;
137
138    fn from_str(s: &str) -> Result<Self, Self::Err> {
139        Self::try_from(ObjectId::from_str(s).map_err(|e| {
140            log::error!("NamedObjectId::from_str error:{}", e);
141            e
142        })?)
143    }
144}
145
146impl<T: ObjectType> TryFrom<&ObjectId> for NamedObjectId<T> {
147    type Error = BuckyError;
148
149    fn try_from(id: &ObjectId) -> Result<Self, Self::Error> {
150        let obj_type_code = id.obj_type_code();
151
152        if obj_type_code == T::obj_type_code() {
153            Ok(Self(*id, None))
154        } else {
155            Err(
156                BuckyError::new(
157                    BuckyErrorCode::InvalidParam,
158                    format!("try convert from object id to named object id failed, mismatch obj_type_code, expect obj_type_code is: {:?}, current obj_type_code is: {:?}", T::obj_type_code(), obj_type_code)
159                )
160            )
161        }
162    }
163}
164
165impl<T: ObjectType> TryFrom<ObjectId> for NamedObjectId<T> {
166    type Error = BuckyError;
167
168    fn try_from(id: ObjectId) -> Result<Self, Self::Error> {
169        let obj_type_code = id.obj_type_code();
170
171        if obj_type_code == T::obj_type_code() {
172            Ok(Self(id, None))
173        } else {
174            Err(
175                BuckyError::new(
176                    BuckyErrorCode::InvalidParam,
177                    format!("try convert from object id to named object id failed, mismatch obj_type_code, expect obj_type_code is: {}, current obj_type_code is:{}", T::obj_type_code().to_string(), obj_type_code.to_string())
178                )
179            )
180        }
181    }
182}
183
184impl<T: ObjectType> AsRef<ObjectId> for NamedObjectId<T> {
185    fn as_ref(&self) -> &ObjectId {
186        &self.0
187    }
188}
189
190impl<T: ObjectType> RawFixedBytes for NamedObjectId<T> {
191    fn raw_bytes() -> Option<usize> {
192        ObjectId::raw_bytes()
193    }
194}
195
196impl<T: ObjectType> RawEncode for NamedObjectId<T> {
197    fn raw_measure(&self, purpose: &Option<RawEncodePurpose>) -> Result<usize, BuckyError> {
198        self.0.raw_measure(purpose)
199    }
200
201    fn raw_encode<'a>(
202        &self,
203        buf: &'a mut [u8],
204        purpose: &Option<RawEncodePurpose>,
205    ) -> Result<&'a mut [u8], BuckyError> {
206        self.0.raw_encode(buf, purpose)
207    }
208}
209
210impl<'de, T: ObjectType> RawDecode<'de> for NamedObjectId<T> {
211    fn raw_decode(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
212        let (id, buf) = ObjectId::raw_decode(buf)?;
213        Ok((
214            Self::try_from(id).map_err(|e| {
215                log::error!("NamedObjectId::raw_decode/try_from error:{}", e);
216                e
217            })?,
218            buf,
219        ))
220    }
221}
222
223impl<T: ObjectType> RawDiff for NamedObjectId<T> {
224    fn diff_measure(&self, right: &Self) -> BuckyResult<usize> {
225        let left = self.object_id();
226        let right = right.object_id();
227        left.diff_measure(right)
228    }
229
230    fn diff<'d>(&self, right: &Self, buf: &'d mut [u8]) -> BuckyResult<&'d mut [u8]> {
231        let size = self.diff_measure(right).map_err(|e| {
232            log::error!("NamedObjectId::diff error:{}", e);
233            e
234        })?;
235
236        if buf.len() < size {
237            let message = format!(
238                "[raw_encode] not enough buffer for NamedObjectId, obj_type:{}, obj_type_code:{:?}",
239                T::obj_type(),
240                T::obj_type_code()
241            );
242            return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, message));
243        }
244
245        self.object_id().diff(right.object_id(), buf)
246    }
247}
248
249impl<'de, T: ObjectType> RawPatch<'de> for NamedObjectId<T> {
250    fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
251        let (object_id, buf) = self.object_id().patch(buf).map_err(|e| {
252            log::error!("NamedObjectId::patch error:{}", e);
253            e
254        })?;
255
256        Ok((
257            NamedObjectId::<T>::try_from(object_id).map_err(|e| {
258                log::error!("NamedObjectId::patch/try_from error:{}", e);
259                e
260            })?,
261            buf,
262        ))
263    }
264}