cyfs_base/objects/
named_object_id.rs1use 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#[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 let type_code = if T::is_dec_app_object() {
74 0b_110000
76 } else {
77 0b_100000
79 };
80
81 hash_value[0] = type_code << 2;
83 } else {
84 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 }
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}