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