1use crate::*;
2
3use base58::{FromBase58, ToBase58};
4use generic_array::typenum::{marker_traits::Unsigned, U32};
5use generic_array::GenericArray;
6use primitive_types::H256;
7use serde::{
8 de::{self, Visitor},
9 Deserialize, Deserializer, Serialize, Serializer,
10};
11use std::fmt;
12use std::hash::{Hash, Hasher};
13use std::str::FromStr;
14
15#[derive(Debug, Clone, Eq, PartialEq)]
16pub enum ObjectCategory {
17 Standard,
18 Core,
19 DecApp,
20 Data,
21}
22
23impl ToString for ObjectCategory {
24 fn to_string(&self) -> String {
25 (match *self {
26 Self::Standard => "standard",
27 Self::Core => "core",
28 Self::DecApp => "dec_app",
29 Self::Data => "data",
30 })
31 .to_owned()
32 }
33}
34
35impl FromStr for ObjectCategory {
36 type Err = BuckyError;
37
38 fn from_str(value: &str) -> Result<Self, Self::Err> {
39 let ret = match value {
40 "standard" => Self::Standard,
41 "core" => Self::Core,
42 "dec_app" => Self::DecApp,
43 "data" => Self::Data,
44 v @ _ => {
45 let msg = format!("unknown object category: {}", v);
46 error!("{}", msg);
47
48 return Err(BuckyError::from(msg));
49 }
50 };
51
52 Ok(ret)
53 }
54}
55
56use std::ops::Range;
57
58pub const OBJECT_ID_BASE58_RANGE: Range<usize> = 43..45;
60
61pub const OBJECT_ID_BASE36_RANGE: Range<usize> = 49..51;
63
64#[derive(Copy, Clone, PartialOrd, PartialEq, Ord, Eq)]
66pub struct ObjectId(GenericArray<u8, U32>);
67
68impl std::fmt::Debug for ObjectId {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 write!(f, "{}", self.to_string())
71 }
72}
73
74impl From<[u8; 32]> for ObjectId {
75 fn from(v: [u8; 32]) -> Self {
76 Self(GenericArray::from(v))
77 }
78}
79
80impl TryFrom<Vec<u8>> for ObjectId {
97 type Error = BuckyError;
98 fn try_from(v: Vec<u8>) -> Result<Self, Self::Error> {
99 if v.len() != 32 {
100 let msg = format!(
101 "ObjectId expected bytes of length {} but it was {}",
102 32,
103 v.len()
104 );
105 error!("{}", msg);
106 return Err(BuckyError::new(BuckyErrorCode::InvalidData, msg));
107 }
108
109 let ar: [u8; 32] = v.try_into().unwrap();
110 Ok(Self(GenericArray::from(ar)))
111 }
112}
113
114impl From<GenericArray<u8, U32>> for ObjectId {
115 fn from(hash: GenericArray<u8, U32>) -> Self {
116 Self(hash)
117 }
118}
119
120impl From<ObjectId> for GenericArray<u8, U32> {
121 fn from(hash: ObjectId) -> Self {
122 hash.0
123 }
124}
125
126impl From<H256> for ObjectId {
127 fn from(val: H256) -> Self {
128 ObjectId::clone_from_slice(val.as_ref()).unwrap()
129 }
130}
131
132impl Into<H256> for ObjectId {
133 fn into(self) -> H256 {
134 H256::from_slice(self.as_slice())
135 }
136}
137
138impl AsRef<GenericArray<u8, U32>> for ObjectId {
139 fn as_ref(&self) -> &GenericArray<u8, U32> {
140 &self.0
141 }
142}
143
144impl Default for ObjectId {
145 fn default() -> Self {
146 ObjectId(GenericArray::default())
147 }
148}
149
150impl ProtobufTransform<ObjectId> for Vec<u8> {
151 fn transform(value: ObjectId) -> BuckyResult<Self> {
152 Ok(Vec::from(value.0.as_slice()))
153 }
154}
155
156impl ProtobufTransform<&ObjectId> for Vec<u8> {
157 fn transform(value: &ObjectId) -> BuckyResult<Self> {
158 Ok(Vec::from(value.0.as_slice()))
159 }
160}
161
162impl ProtobufTransform<Vec<u8>> for ObjectId {
163 fn transform(value: Vec<u8>) -> BuckyResult<Self> {
164 if value.len() != 32 {
165 return Err(BuckyError::new(
166 BuckyErrorCode::InvalidParam,
167 format!(
168 "try convert from vec<u8> to named object id failed, invalid len {}",
169 value.len()
170 ),
171 ));
172 }
173 let mut id = Self::default();
174 unsafe {
175 std::ptr::copy(value.as_ptr(), id.as_mut_slice().as_mut_ptr(), value.len());
176 }
177
178 Ok(id)
179 }
180}
181
182pub const OBJECT_ID_DATA: u8 = 0b_00000000;
183pub const OBJECT_ID_STANDARD: u8 = 0b_00000001;
184pub const OBJECT_ID_CORE: u8 = 0b_00000010;
185pub const OBJECT_ID_DEC_APP: u8 = 0b_00000011;
186
187pub const OBJECT_ID_FLAG_AREA: u8 = 0b_001000;
188pub const OBJECT_ID_FLAG_PK: u8 = 0b_000100;
189pub const OBJECT_ID_FLAG_MN_PK: u8 = 0b_000010;
190pub const OBJECT_ID_FLAG_OWNER: u8 = 0b_000001;
191
192pub struct StandardObjectIdInfo {
193 pub obj_type_code: ObjectTypeCode,
194 pub obj_type: u16,
195 pub area: Option<Area>,
196}
197
198pub struct CoreObjectIdInfo {
199 pub area: Option<Area>,
200 pub has_owner: bool,
201 pub has_single_key: bool,
202 pub has_mn_key: bool,
203}
204
205pub struct DecAppObjectIdInfo {
206 pub area: Option<Area>,
207 pub has_owner: bool,
208 pub has_single_key: bool,
209 pub has_mn_key: bool,
210}
211
212pub enum ObjectIdInfo<'a> {
213 Data(&'a [u8]),
214 Standard(StandardObjectIdInfo),
215 Core(CoreObjectIdInfo),
216 DecApp(DecAppObjectIdInfo),
217}
218
219impl<'a> ObjectIdInfo<'a> {
220 pub fn area(&self) -> &Option<Area> {
221 match self {
222 Self::Data(_) => &None,
223 Self::Standard(v) => &v.area,
224 Self::Core(v) => &v.area,
225 Self::DecApp(v) => &v.area,
226 }
227 }
228
229 pub fn into_area(self) -> Option<Area> {
230 match self {
231 Self::Data(_) => None,
232 Self::Standard(v) => v.area,
233 Self::Core(v) => v.area,
234 Self::DecApp(v) => v.area,
235 }
236 }
237}
238
239pub struct ObjectIdBuilder<'a, T>
240where
241 T: RawEncode + ObjectDesc,
242{
243 t: &'a T,
244 obj_type_code: ObjectTypeCode,
245 area: Option<&'a Area>,
246 has_owner: bool,
247 has_single_key: bool,
248 has_mn_key: bool,
249}
250
251impl<'a, T> ObjectIdBuilder<'a, T>
252where
253 T: RawEncode + ObjectDesc,
254{
255 pub fn new(t: &'a T, obj_type_code: ObjectTypeCode) -> Self {
256 Self {
257 t,
258 obj_type_code,
259 area: None,
260 has_owner: false,
261 has_single_key: false,
262 has_mn_key: false,
263 }
264 }
265
266 pub fn area(mut self, area: Option<&'a Area>) -> Self {
267 self.area = area;
268 self
269 }
270
271 pub fn owner(mut self, value: bool) -> Self {
272 self.has_owner = value;
273 self
274 }
275
276 pub fn single_key(mut self, value: bool) -> Self {
277 self.has_single_key = value;
278 self
279 }
280
281 pub fn mn_key(mut self, value: bool) -> Self {
282 self.has_mn_key = value;
283 self
284 }
285
286 pub fn build(self) -> ObjectId {
287 let mut hash = self.t.raw_hash_value().unwrap();
288 let hash_value = hash.as_mut_slice();
289
290 hash_value[0] = 0;
293 hash_value[1] = 0;
294 hash_value[2] = 0;
295 hash_value[3] = 0;
296 hash_value[4] = 0;
297
298 if !self.t.is_standard_object() {
299 let mut type_code = if self.t.obj_type() > OBJECT_TYPE_CORE_END {
302 0b_110000
305 } else {
306 0b_100000
309 };
310
311 if self.area.is_some() {
313 type_code = type_code | 0b_001000;
314 }
315
316 if self.has_single_key {
317 type_code = type_code | 0b_000100;
318 }
319
320 if self.has_mn_key {
321 type_code = type_code | 0b_000010;
322 }
323
324 if self.has_owner {
325 type_code = type_code | 0b_000001;
326 }
327
328 if self.area.is_some() {
329 let area = self.area.as_ref().unwrap();
330 hash_value[0] = type_code << 2 | (area.country << 7 >> 14) as u8;
339 hash_value[1] = (area.country << 1) as u8 | area.carrier << 4 >> 7;
340 hash_value[2] = area.carrier << 5 | (area.city >> 8) as u8;
341 hash_value[3] = (area.city << 8 >> 8) as u8;
342 hash_value[4] = area.inner;
343 } else {
344 hash_value[0] = type_code << 2;
346 }
347 } else {
348 let type_code = self.obj_type_code.to_u8();
351
352 if self.area.is_some() {
353 let area = self.area.as_ref().unwrap();
362 hash_value[0] = 0b_01000000 | type_code << 4 >> 2 | (area.country << 7 >> 14) as u8;
363 hash_value[1] = (area.country << 1) as u8 | area.carrier << 4 >> 7;
364 hash_value[2] = area.carrier << 5 | (area.city >> 8) as u8;
365 hash_value[3] = (area.city << 8 >> 8) as u8;
366 hash_value[4] = area.inner;
367 } else {
368 hash_value[0] = 0b_01000000 | type_code << 4 >> 2;
369 }
370 };
371
372 drop(hash_value);
373 let id = ObjectId::new(hash.into());
374
375 id
376 }
377}
378
379pub struct ObjectIdDataBuilder<'a> {
380 data: Option<&'a [u8]>,
381}
382
383impl<'a> ObjectIdDataBuilder<'a> {
384 pub fn new() -> Self {
385 Self { data: None }
386 }
387
388 pub fn data(mut self, data: &'a (impl AsRef<[u8]> + ?Sized)) -> Self {
389 self.data = Some(data.as_ref());
390 self
391 }
392
393 pub fn build_empty() -> ObjectId {
394 ObjectIdDataBuilder::new().build().unwrap()
395 }
396
397 pub fn build(self) -> BuckyResult<ObjectId> {
398 let mut id = GenericArray::<u8, U32>::default();
399 if let Some(data) = self.data {
400 let len = data.len();
401 if len > 31 {
402 let msg = format!("invalid object id data len! len={}, max={}", len, 31);
403 error!("{}", msg);
404 return Err(BuckyError::new(BuckyErrorCode::InvalidData, msg));
405 }
406
407 id.as_mut_slice()[0] = len as u8;
408 id.as_mut_slice()[1..(len + 1)].copy_from_slice(data);
409 }
410
411 Ok(ObjectId::new(id))
412 }
413}
414
415#[derive(Copy, Clone, PartialOrd, PartialEq, Ord, Eq)]
416pub struct ObjectIdDistance(GenericArray<u8, U32>);
417
418impl Into<u32> for ObjectIdDistance {
419 fn into(self) -> u32 {
420 let mut last = [0u8; 4];
421 last.copy_from_slice(&self.0.as_slice()[28..]);
422 u32::from_le_bytes(last)
423 }
424}
425
426impl Into<u128> for ObjectIdDistance {
427 fn into(self) -> u128 {
428 let mut last = [0u8; 16];
429 last.copy_from_slice(&self.0.as_slice()[16..]);
430 u128::from_le_bytes(last)
431 }
432}
433
434impl ObjectId {
435 pub fn obj_type_code(&self) -> ObjectTypeCode {
436 ObjectTypeCode::raw_check_type_code(self.as_slice())
437 }
438
439 pub fn info(&self) -> ObjectIdInfo {
440 let buf = self.as_slice();
441 let flag = buf[0];
442
443 let decode_flag = |buf: &[u8]| -> (bool, bool, bool, bool) {
444 let type_code = buf[0] << 2 >> 4;
445 let has_area = type_code & OBJECT_ID_FLAG_AREA == OBJECT_ID_FLAG_AREA;
446 let has_single_key = type_code & OBJECT_ID_FLAG_PK == OBJECT_ID_FLAG_PK;
447 let has_mn_key = type_code & OBJECT_ID_FLAG_MN_PK == OBJECT_ID_FLAG_MN_PK;
448 let has_owner = type_code & OBJECT_ID_FLAG_OWNER == OBJECT_ID_FLAG_OWNER;
449 (has_area, has_single_key, has_mn_key, has_owner)
450 };
451
452 let decode_rea = |buf: &[u8]| -> Option<Area> {
453 let country = (((buf[0] as u16) & 0x3) << 7) | ((buf[1] >> 1) as u16);
463 let carrier = (buf[1] << 7 >> 4) | (buf[2] >> 5);
464 let city = ((buf[2] as u16) << 11 >> 3) | (buf[3] as u16);
465 let inner = buf[4];
466
467 Some(Area::new(country, carrier, city, inner))
468 };
469
470 let try_decode_rea = |buf: &[u8]| -> Option<Area> {
471 if buf[1] == 0b_00000000
472 && buf[2] == 0b_00000000
473 && buf[3] == 0b_00000000
474 && buf[4] == 0b_00000000
475 {
476 None
477 } else {
478 decode_rea(buf)
479 }
480 };
481
482 let obj_bits = flag >> 6;
483
484 match obj_bits {
485 OBJECT_ID_STANDARD => {
486 let obj_type = (flag << 2 >> 4) as u16;
488 let obj_type_code = obj_type.into();
489 let area = try_decode_rea(buf);
490
491 ObjectIdInfo::Standard(StandardObjectIdInfo {
492 obj_type_code,
493 obj_type,
494 area,
495 })
496 }
497 OBJECT_ID_CORE => {
498 let (has_area, has_single_key, has_mn_key, has_owner) = decode_flag(buf);
500 let area = if has_area { decode_rea(buf) } else { None };
501
502 ObjectIdInfo::Core(CoreObjectIdInfo {
503 has_single_key,
504 has_mn_key,
505 has_owner,
506 area,
507 })
508 }
509 OBJECT_ID_DEC_APP => {
510 let (has_area, has_single_key, has_mn_key, has_owner) = decode_flag(buf);
512 let area = if has_area { decode_rea(buf) } else { None };
513
514 ObjectIdInfo::DecApp(DecAppObjectIdInfo {
515 has_single_key,
516 has_mn_key,
517 has_owner,
518 area,
519 })
520 }
521 OBJECT_ID_DATA => ObjectIdInfo::Data(self.data()),
522 _ => {
523 unreachable!();
524 }
525 }
526 }
527
528 pub fn as_slice(&self) -> &[u8] {
529 self.0.as_slice()
530 }
531
532 pub fn as_mut_slice(&mut self) -> &mut [u8] {
533 self.0.as_mut_slice()
534 }
535
536 pub fn new(inner: GenericArray<u8, U32>) -> Self {
537 Self(inner)
538 }
539
540 pub fn clone_from_slice(slice: &[u8]) -> BuckyResult<Self> {
541 if slice.len() != U32::to_usize() {
542 let msg = format!("invalid buf len for ObjectId: len={}", slice.len());
543 error!("{}", msg);
544 return Err(BuckyError::new(BuckyErrorCode::InvalidData, msg));
545 }
546
547 Ok(ObjectId(GenericArray::clone_from_slice(slice)))
548 }
549
550 pub fn to_string(&self) -> String {
551 self.0.as_slice().to_base58()
552 }
553
554 pub fn to_hash_value(&self) -> HashValue {
555 self.0.as_slice().try_into().unwrap()
556 }
557
558 pub fn from_base58(s: &str) -> BuckyResult<Self> {
559 let buf = s.from_base58().map_err(|e| {
560 let msg = format!("convert base58 str to object id failed, str={}, {:?}", s, e);
561 error!("{}", msg);
562 BuckyError::new(BuckyErrorCode::InvalidFormat, msg)
563 })?;
564
565 if buf.len() != 32 {
566 let msg = format!(
567 "convert base58 str to object id failed, len unmatch: str={}",
568 s
569 );
570 return Err(BuckyError::new(BuckyErrorCode::InvalidFormat, msg));
571 }
572
573 Ok(Self::try_from(buf).unwrap())
574 }
575
576 pub fn to_base36(&self) -> String {
577 self.0.as_slice().to_base36()
578 }
579
580 pub fn from_base36(s: &str) -> BuckyResult<Self> {
581 let buf = s.from_base36()?;
582 if buf.len() != 32 {
583 let msg = format!(
584 "convert base36 str to object id failed, len unmatch: str={}",
585 s
586 );
587 return Err(BuckyError::new(BuckyErrorCode::InvalidFormat, msg));
588 }
589
590 Ok(Self::try_from(buf).unwrap())
591 }
592
593 pub fn object_category(&self) -> ObjectCategory {
594 let flags = self.as_slice()[0] >> 6;
595 match flags {
596 OBJECT_ID_DATA => ObjectCategory::Data,
597 OBJECT_ID_STANDARD => ObjectCategory::Standard,
598 OBJECT_ID_CORE => ObjectCategory::Core,
599 OBJECT_ID_DEC_APP => ObjectCategory::DecApp,
600 _ => {
601 unreachable!();
602 }
603 }
604 }
605
606 pub fn is_data(&self) -> bool {
607 let buf = self.as_slice();
608 let flag = buf[0];
609 flag >> 6 == OBJECT_ID_DATA
610 }
611
612 pub fn is_standard_object(&self) -> bool {
613 let buf = self.as_slice();
614 let flag = buf[0];
615 flag >> 6 == OBJECT_ID_STANDARD
616 }
617
618 pub fn is_core_object(&self) -> bool {
619 let buf = self.as_slice();
620 let flag = buf[0];
621 flag >> 6 == OBJECT_ID_CORE
622 }
623
624 pub fn is_dec_app_object(&self) -> bool {
625 let buf = self.as_slice();
626 let flag = buf[0];
627 flag >> 6 == OBJECT_ID_DEC_APP
628 }
629
630 pub fn distance_of(&self, other: &Self) -> ObjectIdDistance {
631 let mut v = GenericArray::<u8, U32>::default();
632 for (i, (l, r)) in self
633 .0
634 .as_slice()
635 .iter()
636 .zip(other.0.as_slice().iter())
637 .enumerate()
638 {
639 v[i] = *l ^ *r;
640 }
641 ObjectIdDistance(v)
642 }
643
644 pub fn data_len(&self) -> u8 {
645 self.as_slice()[0] & 0b_00111111
646 }
647
648 pub fn data(&self) -> &[u8] {
649 let len = self.data_len();
650 &self.as_slice()[1..len as usize + 1]
651 }
652
653 pub fn data_as_utf8_string(&self) -> BuckyResult<&str> {
654 std::str::from_utf8(self.data()).map_err(|e| {
655 let msg = format!(
656 "invalid object id data as utf8 string! id={}, {}",
657 self.to_string(),
658 e
659 );
660 error!("{}", msg);
661 BuckyError::new(BuckyErrorCode::InvalidData, msg)
662 })
663 }
664
665 pub fn data_as_utf8_string_unchecked(&self) -> &str {
666 unsafe { std::str::from_utf8_unchecked(self.data()) }
667 }
668
669 pub fn is_chunk_id(&self) -> bool {
670 match self.obj_type_code() {
671 ObjectTypeCode::Chunk => true,
672 _ => false,
673 }
674 }
675
676 pub fn as_chunk_id(&self) -> &ChunkId {
677 unsafe { std::mem::transmute::<&ObjectId, &ChunkId>(&self) }
678 }
679
680 pub fn as_named_object_id<T: ObjectType>(&self) -> &NamedObjectId<T> {
681 unsafe { std::mem::transmute::<&ObjectId, &NamedObjectId<T>>(&self) }
682 }
683
684 pub fn is_default(&self) -> bool {
685 self == &ObjectId::default()
686 }
687}
688
689impl RawFixedBytes for ObjectId {
690 fn raw_bytes() -> Option<usize> {
691 Some(U32::to_usize())
692 }
693}
694
695impl RawEncode for ObjectId {
696 fn raw_measure(&self, _purpose: &Option<RawEncodePurpose>) -> Result<usize, BuckyError> {
697 Ok(U32::to_usize())
698 }
699
700 fn raw_encode<'a>(
701 &self,
702 buf: &'a mut [u8],
703 _purpose: &Option<RawEncodePurpose>,
704 ) -> Result<&'a mut [u8], BuckyError> {
705 let bytes = Self::raw_bytes().unwrap();
706 if buf.len() < bytes {
707 let msg = format!(
708 "not enough buffer for encode ObjectId, except={}, got={}",
709 bytes,
710 buf.len()
711 );
712 error!("{}", msg);
713
714 return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg));
715 }
716 unsafe {
717 std::ptr::copy(self.as_slice().as_ptr(), buf.as_mut_ptr(), bytes);
718 }
719
720 Ok(&mut buf[bytes..])
721 }
722}
723
724impl<'de> RawDecode<'de> for ObjectId {
725 fn raw_decode(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
726 let bytes = Self::raw_bytes().unwrap();
727 if buf.len() < bytes {
728 let msg = format!(
729 "not enough buffer for decode ObjectId, except={}, got={}",
730 bytes,
731 buf.len()
732 );
733 error!("{}", msg);
734
735 return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg));
736 }
737 let mut _id = Self::default();
738 unsafe {
739 std::ptr::copy(buf.as_ptr(), _id.as_mut_slice().as_mut_ptr(), bytes);
740 }
741 Ok((_id, &buf[bytes..]))
742 }
743}
744
745impl FromStr for ObjectId {
746 type Err = BuckyError;
747 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
748 if OBJECT_ID_BASE36_RANGE.contains(&s.len()) {
749 Self::from_base36(s)
750 } else {
751 Self::from_base58(s)
752 }
753 }
754}
755
756impl std::fmt::Display for ObjectId {
757 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
758 write!(f, "{}", self.to_string())
759 }
760}
761
762impl Hash for ObjectId {
763 fn hash<H: Hasher>(&self, state: &mut H) {
764 let mut buff = [0 as u8; 32];
765 let _ = self.raw_encode(buff.as_mut(), &None).unwrap();
766 state.write(buff.as_ref());
767 }
768}
769
770impl Serialize for ObjectId {
771 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
772 where
773 S: Serializer,
774 {
775 serializer.serialize_str(&self.to_string())
776 }
777}
778
779impl<'de> Deserialize<'de> for ObjectId {
780 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
781 where
782 D: Deserializer<'de>,
783 {
784 struct RawObjectIdVisitor;
785 impl<'de> Visitor<'de> for RawObjectIdVisitor {
786 type Value = ObjectId;
787 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
788 write!(formatter, "{}", "an ObjectId")
789 }
790 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
791 where
792 E: de::Error,
793 {
794 ObjectId::from_str(v).map_err(|err| E::custom(err.to_string()))
795 }
796 }
797 deserializer.deserialize_str(RawObjectIdVisitor)
798 }
799}
800
801impl RawDiff for ObjectId {
802 fn diff_measure(&self, right: &Self) -> BuckyResult<usize> {
803 let data = self.as_ref();
804 let r = right.as_ref();
805 data.diff_measure(r)
806 }
807
808 fn diff<'d>(&self, right: &Self, buf: &'d mut [u8]) -> BuckyResult<&'d mut [u8]> {
809 let size = self.diff_measure(right).map_err(|e| {
810 log::error!("ObjectId::diff/diff_measure error:{}", e);
811 e
812 })?;
813
814 if buf.len() < size {
815 return Err(BuckyError::new(
816 BuckyErrorCode::OutOfLimit,
817 "[raw_encode] not enough buffer for ObjectId",
818 ));
819 }
820
821 self.as_ref().diff(right.as_ref(), buf)
822 }
823}
824
825impl<'de> RawPatch<'de> for ObjectId {
826 fn patch(self, buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
827 let data: GenericArray<u8, U32> = self.into();
828 let (data, buf) = data.patch(buf).map_err(|e| {
829 log::error!("ObjectId::patch/data error:{}", e);
830 e
831 })?;
832 Ok((ObjectId::from(data), buf))
833 }
834}
835
836#[cfg(test)]
837mod test {
838 use crate::*;
839
840 #[test]
841 fn test_data() {
842 let data = "hello!!! first id";
843 let id = ObjectIdDataBuilder::new().data(data).build().unwrap();
844 assert!(id.is_data());
845 assert!(!id.is_standard_object());
846 assert!(!id.is_core_object());
847 assert!(!id.is_dec_app_object());
848
849 println!("len={}, {}", id.data_len(), id.to_string());
850
851 let data2 = id.data();
852 assert_eq!(data2.len(), data.as_bytes().len());
853 assert_eq!(data2, data.as_bytes());
854 assert_eq!(id.data_as_utf8_string_unchecked(), data);
855
856 let id = ObjectIdDataBuilder::build_empty();
857 assert!(id.is_data());
858 println!("len={}, {}", id.data_len(), id.to_string());
859 assert_eq!(id.data_len(), 0);
860 assert_eq!(id.data().len(), 0);
861
862 let error_data = "1234567890123456789012345678901234567890";
863 let ret = ObjectIdDataBuilder::new().data(error_data).build();
864 assert!(ret.is_err());
865
866 let data = hash_data("1233".as_bytes());
867 let id = ObjectIdDataBuilder::new()
868 .data(&data.as_slice()[0..31])
869 .build()
870 .unwrap();
871 println!("len={}, {}", id.data_len(), id.to_string());
872
873 assert_eq!(id.data_len(), 31);
874 assert_eq!(id.data(), &data.as_slice()[0..31]);
875 id.data_as_utf8_string().unwrap_err();
876
877 assert_eq!(id.object_category(), ObjectCategory::Data);
878
879 match id.info() {
880 ObjectIdInfo::Data(v) => {
881 assert_eq!(v, &data.as_slice()[0..31]);
882 }
883 _ => unreachable!(),
884 }
885
886 }
889}