1use crate::*;
2
3use std::convert::TryFrom;
4use std::marker::PhantomData;
5
6#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
7pub struct TypelessObjectBodyContent {
8 version: u8,
10 format: u8,
11
12 content_buf: Vec<u8>,
13}
14
15impl BodyContent for TypelessObjectBodyContent {
16 fn version(&self) -> u8 {
17 self.version
18 }
19
20 fn format(&self) -> u8 {
21 self.format
22 }
23}
24
25impl TypelessObjectBodyContent {
26 fn version(&self) -> u8 {
27 self.version
28 }
29
30 fn format(&self) -> u8 {
31 self.format
32 }
33
34 pub fn data(&self) -> &[u8] {
35 &self.content_buf
36 }
37}
38
39impl RawEncode for TypelessObjectBodyContent {
40 fn raw_measure(&self, _purpose: &Option<RawEncodePurpose>) -> BuckyResult<usize> {
41 let len = self.content_buf.len();
42
43 Ok(len)
44 }
45
46 fn raw_encode<'a>(
47 &self,
48 buf: &'a mut [u8],
49 _purpose: &Option<RawEncodePurpose>,
50 ) -> BuckyResult<&'a mut [u8]> {
51 let len = self.content_buf.len();
52
53 assert!(buf.len() >= len);
55
56 unsafe {
58 std::ptr::copy(self.content_buf.as_ptr(), buf.as_mut_ptr(), len);
59 }
60 let buf = &mut buf[len..];
61
62 Ok(buf)
63 }
64}
65
66impl<'de> RawDecode<'de> for TypelessObjectBodyContent {
67 fn raw_decode(buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
68 let opt = RawDecodeOption::default();
69 Self::raw_decode_with_option(buf, &opt)
70 }
71
72 fn raw_decode_with_option(
73 buf: &'de [u8],
74 opt: &RawDecodeOption,
75 ) -> BuckyResult<(Self, &'de [u8])> {
76 let size = buf.len();
78
79 let mut content_buf = vec![0u8; size];
81 unsafe {
82 std::ptr::copy(buf.as_ptr(), content_buf.as_mut_ptr(), size);
83 }
84 let buf = &buf[size..];
85
86 Ok((
87 Self {
88 version: opt.version,
89 format: opt.format,
90 content_buf,
91 },
92 buf,
93 ))
94 }
95}
96
97#[derive(Clone, Debug)]
102pub struct TypelessObjectDesc {
103 obj_type: u16,
105 dec_id: Option<ObjectId>,
106 ref_objects: Option<Vec<ObjectLink>>,
107 prev: Option<ObjectId>,
108 create_timestamp: Option<HashValue>,
109 create_time: Option<u64>,
110 expired_time: Option<u64>,
111 owner: Option<ObjectId>,
113 area: Option<Area>,
114 author: Option<ObjectId>,
115 single_public_key: Option<PublicKey>,
116 mn_public_key: Option<MNPublicKey>,
117
118 version: u8,
120 format: u8,
121
122 desc_content_len: u16,
123 desc_content_buf: Vec<u8>,
124}
125
126impl ObjectDesc for TypelessObjectDesc {
127 fn obj_type(&self) -> u16 {
128 self.obj_type
129 }
130
131 fn calculate_id(&self) -> ObjectId {
132 ObjectIdBuilder::new(self, self.obj_type_code())
133 .area(self.area.area_ref().as_ref())
134 .single_key(self.single_public_key.is_some())
135 .mn_key(self.mn_public_key.is_some())
136 .owner(self.owner.is_some())
137 .build()
138 }
139
140 fn dec_id(&self) -> &Option<ObjectId> {
141 &self.dec_id
142 }
143
144 fn ref_objs(&self) -> &Option<Vec<ObjectLink>> {
145 &self.ref_objects
146 }
147
148 fn prev(&self) -> &Option<ObjectId> {
149 &self.prev
150 }
151
152 fn create_timestamp(&self) -> &Option<HashValue> {
153 &self.create_timestamp
154 }
155
156 fn create_time(&self) -> u64 {
157 self.create_time.unwrap_or(0)
158 }
159
160 fn option_create_time(&self) -> Option<u64> {
161 self.create_time
162 }
163
164 fn expired_time(&self) -> Option<u64> {
165 self.expired_time
166 }
167}
168
169impl TypelessObjectDesc {
171 pub fn owner(&self) -> &Option<ObjectId> {
172 &self.owner
173 }
174
175 pub fn area(&self) -> &Option<Area> {
176 &self.area
177 }
178
179 pub fn author(&self) -> &Option<ObjectId> {
180 &self.author
181 }
182
183 pub fn version(&self) -> u8 {
184 self.version
185 }
186
187 pub fn format(&self) -> u8 {
188 self.format
189 }
190
191 pub fn content(&self) -> &Vec<u8> {
192 &self.desc_content_buf
193 }
194
195 pub fn convert_to<DescContentT>(self) -> BuckyResult<NamedObjectDesc<DescContentT>>
196 where
197 DescContentT: for<'de> RawDecode<'de> + DescContent + Sync + Send + Clone,
198 {
199 let buf = &self.desc_content_buf;
201 let opt = RawDecodeOption {
202 version: self.version,
203 format: self.format,
204 };
205
206 let (desc_content, _) = DescContentT::raw_decode_with_option(buf, &opt).map_err(|e| {
207 log::error!("TypelessObjectDesc::convert_to/desc_content error:{}", e);
208 e
209 })?;
210
211 let builder = NamedObjectDesc::<DescContentT>::new(desc_content);
212 let basic_desc = builder
213 .option_dec_id(self.dec_id)
214 .option_ref_objects(self.ref_objects)
215 .option_prev(self.prev)
216 .option_create_timestamp(self.create_timestamp)
217 .option_create_time(self.create_time)
218 .option_expired_time(self.expired_time)
219 .option_owner(
220 DescContentT::OwnerType::from_type_less(self.owner).map_err(|e| {
221 log::error!("TypelessObjectDesc::convert_to/option_owner error:{}", e);
222 e
223 })?,
224 )
225 .option_area(
226 DescContentT::AreaType::from_type_less(self.area).map_err(|e| {
227 log::error!("TypelessObjectDesc::convert_to/option_area error:{}", e);
228 e
229 })?,
230 )
231 .option_author(
232 DescContentT::AuthorType::from_type_less(self.author).map_err(|e| {
233 log::error!("TypelessObjectDesc::convert_to/option_author error:{}", e);
234 e
235 })?,
236 )
237 .public_key(
238 DescContentT::PublicKeyType::from_type_less(
239 self.single_public_key,
240 self.mn_public_key,
241 )
242 .map_err(|e| {
243 log::error!("TypelessObjectDesc::convert_to/public_key error:{}", e);
244 e
245 })?,
246 )
247 .build();
248
249 Ok(basic_desc)
250 }
251
252 pub fn public_key(&self) -> Option<PublicKeyRef> {
253 if self.single_public_key.is_some() {
254 let key = self.single_public_key.as_ref().unwrap();
255 Some(key.into())
256 } else if self.mn_public_key.is_some() {
257 let key = self.mn_public_key.as_ref().unwrap();
258 Some(key.into())
259 } else {
260 None
261 }
262 }
263}
264
265impl RawEncode for TypelessObjectDesc {
270 fn raw_measure(&self, purpose: &Option<RawEncodePurpose>) -> BuckyResult<usize> {
271 let mut ctx = NamedObjectContext::new(self.obj_type, 0);
272 let size = ctx.raw_measure(purpose).map_err(|e|{
273 error!("TypelessObjectDesc::raw_measure/ctx.raw_measure error:{}, obj_type:{}", e, self.obj_type);
274 e
275 })?
276 + self.raw_measure_with_context(&mut ctx, purpose).map_err(|e|{
277 error!("TypelessObjectDesc::raw_measure/raw_measure_with_context error:{}, obj_type:{}", e, self.obj_type);
278 e
279 })?;
280
281 Ok(size)
282 }
283
284 fn raw_encode<'a>(
285 &self,
286 buf: &'a mut [u8],
287 purpose: &Option<RawEncodePurpose>,
288 ) -> BuckyResult<&'a mut [u8]> {
289 let mut ctx = NamedObjectContext::new(self.obj_type, 0);
290
291 let size = self
292 .raw_measure_with_context(&mut ctx, purpose)
293 .map_err(|e| {
294 error!(
295 "TypelessObjectDesc::raw_encode/raw_measure_with_context error:{}, obj_type:{}",
296 e, self.obj_type
297 );
298 e
299 })?;
300
301 assert!(buf.len() >= size);
302
303 let buf = ctx.raw_encode(buf, purpose).map_err(|e| {
304 error!(
305 "TypelessObjectDesc::raw_encode/ctx.raw_encode error:{}, obj_type:{}",
306 e, self.obj_type
307 );
308 e
309 })?;
310
311 let buf = self
312 .raw_encode_with_context(buf, &mut ctx, purpose)
313 .map_err(|e| {
314 error!(
315 "TypelessObjectDesc::raw_encode/raw_encode_with_context error:{}, obj_type:{}",
316 e, self.obj_type
317 );
318 e
319 })?;
320
321 Ok(buf)
322 }
323
324 fn raw_encode_to_buffer(&self) -> BuckyResult<Vec<u8>> {
325 let mut ctx = NamedObjectContext::new(self.obj_type, 0);
326 let size = ctx.raw_measure(&None).map_err(|e|{
327 error!("TypelessObjectDesc::raw_measure/ctx error:{}, obj_type:{}", e, self.obj_type);
328 e
329 })? + self.raw_measure_with_context(&mut ctx, &None).map_err(|e|{
330 error!("TypelessObjectDesc::raw_measure/raw_measure_with_context error:{}, obj_type:{}", e, self.obj_type);
331 e
332 })?;
333
334 let mut buf = vec![0u8; size];
335 let left_buf = ctx.raw_encode(&mut buf, &None).map_err(|e| {
336 error!(
337 "TypelessObjectDesc::raw_encode/ctx.raw_encode error:{}, obj_type:{}",
338 e, self.obj_type
339 );
340 e
341 })?;
342
343 let left_buf = self.raw_encode_with_context(left_buf, &mut ctx, &None).map_err(|e|{
344 error!("TypelessObjectDesc::raw_encode/self.raw_encode_with_context error:{}, obj_type:{}", e, self.obj_type);
345 e
346 })?;
347 if left_buf.len() != 0 {
348 warn!("encode body content by remaining buf is not empty! obj_type={}, body_size={}, remaining={}", self.obj_type, size, left_buf.len());
349 }
351
352 Ok(buf)
353 }
354
355 fn raw_hash_encode(&self) -> BuckyResult<Vec<u8>> {
356 let mut ctx = NamedObjectContext::new(self.obj_type, 0);
357 let size = ctx.raw_measure(&Some(RawEncodePurpose::Hash)).map_err(|e|{
358 error!("TypelessObjectDesc::raw_hash_encode/ctx error:{}, obj_type:{}", e, self.obj_type);
359 e
360 })? + self.raw_measure_with_context(&mut ctx, &Some(RawEncodePurpose::Hash)).map_err(|e|{
361 error!("NamedObjectDesc<T>::raw_hash_encode/raw_measure_with_context error:{}, obj_type:{}", e, self.obj_type);
362 e
363 })?;
364
365 let mut buf = vec![0u8; size];
366 let left_buf = ctx
367 .raw_encode(&mut buf, &Some(RawEncodePurpose::Hash))
368 .map_err(|e| {
369 error!(
370 "TypelessObjectDesc::raw_hash_encode/ctx.raw_encode error:{}, obj_type:{}",
371 e, self.obj_type
372 );
373 e
374 })?;
375
376 let left_buf = self.raw_encode_with_context(left_buf, &mut ctx, &Some(RawEncodePurpose::Hash)).map_err(|e|{
377 error!("NamedObjectDesc<T>::raw_hash_encode/self.raw_encode_with_context error:{}, obj_type:{}", e, self.obj_type());
378 e
379 })?;
380 if left_buf.len() != 0 {
381 warn!("decode body content by remaining buf is not empty! obj_type={}, body_size={}, remaining={}", self.obj_type, size, left_buf.len());
382 }
384
385 Ok(buf)
386 }
387}
388
389impl RawEncodeWithContext<NamedObjectContext> for TypelessObjectDesc {
394 fn raw_measure_with_context(
395 &self,
396 ctx: &mut NamedObjectContext,
397 purpose: &Option<RawEncodePurpose>,
398 ) -> BuckyResult<usize> {
399 let mut size = 0;
401
402 if self.dec_id.is_some() {
407 ctx.with_dec_id();
408 size = size
409 + self.dec_id.unwrap().raw_measure(purpose).map_err(|e| {
410 log::error!(
411 "TypelessObjectDesc::raw_measure_with_context/dec_id error:{}",
412 e
413 );
414 e
415 })?;
416 }
417
418 if self.ref_objects.is_some() {
419 ctx.with_ref_objects();
420 size = size
421 + self
422 .ref_objects
423 .as_ref()
424 .unwrap()
425 .raw_measure(purpose)
426 .map_err(|e| {
427 log::error!(
428 "TypelessObjectDesc::raw_measure_with_context/ref_objects error:{}",
429 e
430 );
431 e
432 })?;
433 }
434
435 if self.prev.is_some() {
436 ctx.with_prev();
437 size = size
438 + self.prev.unwrap().raw_measure(purpose).map_err(|e| {
439 log::error!(
440 "TypelessObjectDesc::raw_measure_with_context/prev error:{}",
441 e
442 );
443 e
444 })?;
445 }
446
447 if self.create_timestamp.is_some() {
448 ctx.with_create_timestamp();
449 size = size
450 + self
451 .create_timestamp
452 .unwrap()
453 .raw_measure(purpose)
454 .map_err(|e| {
455 log::error!(
456 "TypelessObjectDesc::raw_measure_with_context/create_timestamp error:{}",
457 e
458 );
459 e
460 })?;
461 }
462
463 if self.create_time.is_some() {
464 ctx.with_create_time();
465 size = size + u64::raw_bytes().unwrap();
466 }
467
468 if self.expired_time.is_some() {
469 ctx.with_expired_time();
470 size = size
471 + self
472 .expired_time
473 .unwrap()
474 .raw_measure(purpose)
475 .map_err(|e| {
476 log::error!(
477 "TypelessObjectDesc::raw_measure_with_context/expired_time error:{}",
478 e
479 );
480 e
481 })?;
482 }
483
484 if self.owner.is_some() {
489 ctx.with_owner();
490 size = size
491 + self
492 .owner
493 .as_ref()
494 .unwrap()
495 .raw_measure(purpose)
496 .map_err(|e| {
497 log::error!(
498 "TypelessObjectDesc::raw_measure_with_context/owner error:{}",
499 e
500 );
501 e
502 })?;
503 }
504
505 if self.area.is_some() {
506 ctx.with_area();
507 size = size
508 + self
509 .area
510 .as_ref()
511 .unwrap()
512 .raw_measure(purpose)
513 .map_err(|e| {
514 log::error!(
515 "TypelessObjectDesc::raw_measure_with_context/area error:{}",
516 e
517 );
518 e
519 })?;
520 }
521
522 if self.author.is_some() {
523 ctx.with_author();
524 size = size
525 + self
526 .author
527 .as_ref()
528 .unwrap()
529 .raw_measure(purpose)
530 .map_err(|e| {
531 log::error!(
532 "TypelessObjectDesc::raw_measure_with_context/author error:{}",
533 e
534 );
535 e
536 })?;
537 }
538
539 if self.single_public_key.is_some() {
540 ctx.with_public_key();
541 size = size + u8::raw_bytes().unwrap();
542 size = size
543 + self
544 .single_public_key
545 .as_ref()
546 .unwrap()
547 .raw_measure(purpose)
548 .map_err(|e| {
549 log::error!(
550 "TypelessObjectDesc::raw_measure_with_context/single_public_key error:{}",
551 e
552 );
553 e
554 })?;
555 } else if self.mn_public_key.is_some() {
556 ctx.with_public_key();
557 size = size + u8::raw_bytes().unwrap();
558 size = size
559 + self
560 .mn_public_key
561 .as_ref()
562 .unwrap()
563 .raw_measure(purpose)
564 .map_err(|e| {
565 log::error!(
566 "TypelessObjectDesc::raw_measure_with_context/mn_public_key error:{}",
567 e
568 );
569 e
570 })?;
571 }
572
573 size += u16::raw_bytes().unwrap();
575
576 size += u16::raw_bytes().unwrap();
578 size += self.desc_content_buf.len();
579
580 Ok(size)
581 }
582
583 fn raw_encode_with_context<'a>(
584 &self,
585 buf: &'a mut [u8],
586 _ctx: &mut NamedObjectContext,
587 purpose: &Option<RawEncodePurpose>,
588 ) -> BuckyResult<&'a mut [u8]> {
589 let mut buf = buf;
591 if self.dec_id.is_some() {
592 buf = self.dec_id.unwrap().raw_encode(buf, purpose).map_err(|e| {
593 log::error!(
594 "TypelessObjectDesc::raw_encode_with_context/dec_id error:{}",
595 e
596 );
597 e
598 })?;
599 }
600
601 if self.ref_objects.is_some() {
602 buf = self
603 .ref_objects
604 .as_ref()
605 .unwrap()
606 .raw_encode(buf, purpose)
607 .map_err(|e| {
608 log::error!(
609 "TypelessObjectDesc::raw_encode_with_context/ref_objects error:{}",
610 e
611 );
612 e
613 })?;
614 }
615
616 if self.prev.is_some() {
617 buf = self.prev.unwrap().raw_encode(buf, purpose).map_err(|e| {
618 log::error!(
619 "TypelessObjectDesc::raw_encode_with_context/prev error:{}",
620 e
621 );
622 e
623 })?;
624 }
625
626 if self.create_timestamp.is_some() {
627 buf = self
628 .create_timestamp
629 .unwrap()
630 .raw_encode(buf, purpose)
631 .map_err(|e| {
632 log::error!(
633 "TypelessObjectDesc::raw_encode_with_context/create_timestamp error:{}",
634 e
635 );
636 e
637 })?;
638 }
639
640 if self.create_time.is_some() {
641 buf = self
642 .create_time
643 .unwrap()
644 .raw_encode(buf, purpose)
645 .map_err(|e| {
646 log::error!(
647 "TypelessObjectDesc::raw_encode_with_context/create_time error:{}",
648 e
649 );
650 e
651 })?;
652 }
653
654 if self.expired_time.is_some() {
655 buf = self
656 .expired_time
657 .unwrap()
658 .raw_encode(buf, purpose)
659 .map_err(|e| {
660 log::error!(
661 "TypelessObjectDesc::raw_encode_with_context/expired_time error:{}",
662 e
663 );
664 e
665 })?;
666 }
667
668 if self.owner.is_some() {
669 buf = self.owner.unwrap().raw_encode(buf, purpose).map_err(|e| {
670 log::error!(
671 "TypelessObjectDesc::raw_encode_with_context/owner error:{}",
672 e
673 );
674 e
675 })?;
676 }
677
678 if self.area.is_some() {
679 buf = self
680 .area
681 .as_ref()
682 .unwrap()
683 .raw_encode(buf, purpose)
684 .map_err(|e| {
685 log::error!(
686 "TypelessObjectDesc::raw_encode_with_context/area error:{}",
687 e
688 );
689 e
690 })?;
691 }
692
693 if self.author.is_some() {
694 buf = self.author.unwrap().raw_encode(buf, purpose).map_err(|e| {
695 log::error!(
696 "TypelessObjectDesc::raw_encode_with_context/author error:{}",
697 e
698 );
699 e
700 })?;
701 }
702
703 if self.single_public_key.is_some() {
704 buf = OBJECT_PUBLIC_KEY_SINGLE
705 .raw_encode(buf, purpose)
706 .map_err(|e| {
707 log::error!(
708 "TypelessObjectDesc::raw_encode_with_context/key_flag_single error:{}",
709 e
710 );
711 e
712 })?;
713
714 buf = self
715 .single_public_key
716 .as_ref()
717 .unwrap()
718 .raw_encode(buf, purpose)
719 .map_err(|e| {
720 log::error!(
721 "TypelessObjectDesc::raw_encode_with_context/single_public_key error:{}",
722 e
723 );
724 e
725 })?;
726 } else if self.mn_public_key.is_some() {
727 buf = OBJECT_PUBLIC_KEY_MN.raw_encode(buf, purpose).map_err(|e| {
728 log::error!(
729 "TypelessObjectDesc::raw_encode_with_context/key_flag_mn error:{}",
730 e
731 );
732 e
733 })?;
734
735 buf = self
736 .mn_public_key
737 .as_ref()
738 .unwrap()
739 .raw_encode(buf, purpose)
740 .map_err(|e| {
741 log::error!(
742 "TypelessObjectDesc::raw_encode_with_context/mn_public_key error:{}",
743 e
744 );
745 e
746 })?;
747 } else {
748 }
750
751 buf = self.version().raw_encode(buf, purpose).map_err(|e| {
753 error!(
754 "TypelessObjectDesc::raw_encode_with_context/version error:{}, obj_type:{}",
755 e,
756 self.obj_type()
757 );
758 e
759 })?;
760
761 buf = self.format().raw_encode(buf, purpose).map_err(|e| {
763 error!(
764 "TypelessObjectDesc::raw_encode_with_context/format error:{}, obj_type:{}",
765 e,
766 self.obj_type()
767 );
768 e
769 })?;
770
771 buf = self
773 .desc_content_len
774 .raw_encode(buf, purpose)
775 .map_err(|e| {
776 log::error!(
777 "TypelessObjectDesc::raw_encode_with_context/desc_content_len error:{}",
778 e
779 );
780 e
781 })?;
782
783 unsafe {
785 std::ptr::copy(
786 self.desc_content_buf.as_ptr(),
787 buf.as_mut_ptr(),
788 self.desc_content_len as usize,
789 );
790 }
791 let buf = &mut buf[self.desc_content_buf.len()..];
792
793 Ok(buf)
794 }
795}
796
797impl<'de> RawDecodeWithContext<'de, NamedObjectContext> for TypelessObjectDesc {
802 fn raw_decode_with_context(
803 buf: &'de [u8],
804 ctx: NamedObjectContext,
805 ) -> BuckyResult<(Self, &'de [u8])> {
806 let obj_type = ctx.obj_type();
807
808 let (dec_id, buf) = if ctx.has_dec_id() {
813 ObjectId::raw_decode(buf)
814 .map(|(v, buf)| (Some(v), buf))
815 .map_err(|e| {
816 log::error!(
817 "TypelessObjectDesc::raw_decode_with_context/dec_id error:{}",
818 e
819 );
820 e
821 })?
822 } else {
823 (None, buf)
824 };
825
826 let (ref_objects, buf) = if ctx.has_ref_objects() {
827 Vec::<ObjectLink>::raw_decode(buf)
828 .map(|(v, buf)| (Some(v), buf))
829 .map_err(|e| {
830 log::error!(
831 "TypelessObjectDesc::raw_decode_with_context/ref_objects error:{}",
832 e
833 );
834 e
835 })?
836 } else {
837 (None, buf)
838 };
839
840 let (prev, buf) = if ctx.has_prev() {
841 ObjectId::raw_decode(buf)
842 .map(|(v, buf)| (Some(v), buf))
843 .map_err(|e| {
844 log::error!(
845 "TypelessObjectDesc::raw_decode_with_context/prev error:{}",
846 e
847 );
848 e
849 })?
850 } else {
851 (None, buf)
852 };
853
854 let (create_timestamp, buf) = if ctx.has_create_time_stamp() {
855 HashValue::raw_decode(buf)
856 .map(|(v, buf)| (Some(v), buf))
857 .map_err(|e| {
858 log::error!(
859 "TypelessObjectDesc::raw_decode_with_context/create_timestamp error:{}",
860 e
861 );
862 e
863 })?
864 } else {
865 (None, buf)
866 };
867
868 let (create_time, buf) = if ctx.has_create_time() {
869 u64::raw_decode(buf)
870 .map(|(v, buf)| (Some(v), buf))
871 .map_err(|e| {
872 log::error!(
873 "TypelessObjectDesc::raw_decode_with_context/create_time error:{}",
874 e
875 );
876 e
877 })?
878 } else {
879 (None, buf)
880 };
881
882 let (expired_time, buf) = if ctx.has_expired_time() {
883 u64::raw_decode(buf)
884 .map(|(v, buf)| (Some(v), buf))
885 .map_err(|e| {
886 log::error!(
887 "TypelessObjectDesc::raw_decode_with_context/expired_time error:{}",
888 e
889 );
890 e
891 })?
892 } else {
893 (None, buf)
894 };
895
896 let (owner, buf) = if ctx.has_owner() {
900 let (owner, buf) = ObjectId::raw_decode(buf).map_err(|e| {
901 log::error!(
902 "TypelessObjectDesc::raw_decode_with_context/owner error:{}",
903 e
904 );
905 e
906 })?;
907 (Some(owner), buf)
908 } else {
909 (None, buf)
910 };
911
912 let (area, buf) = if ctx.has_area() {
913 let (area, buf) = Area::raw_decode(buf).map_err(|e| {
914 log::error!(
915 "TypelessObjectDesc::raw_decode_with_context/area error:{}",
916 e
917 );
918 e
919 })?;
920 (Some(area), buf)
921 } else {
922 (None, buf)
923 };
924
925 let (author, buf) = if ctx.has_author() {
926 let (author, buf) = ObjectId::raw_decode(buf).map_err(|e| {
927 log::error!(
928 "TypelessObjectDesc::raw_decode_with_context/author error:{}",
929 e
930 );
931 e
932 })?;
933 (Some(author), buf)
934 } else {
935 (None, buf)
936 };
937
938 let (single_public_key, mn_public_key, buf) = if ctx.has_public_key() {
939 let (key_type, buf) = u8::raw_decode(buf).map_err(|e| {
940 log::error!(
941 "TypelessObjectDesc::raw_decode_with_context/key_type error:{}",
942 e
943 );
944 e
945 })?;
946 match key_type {
947 OBJECT_PUBLIC_KEY_SINGLE => {
948 let (single_public_key, buf) = PublicKey::raw_decode(buf).map_err(|e|{
949 log::error!("TypelessObjectDesc::raw_decode_with_context/single_public_key error:{}", e);
950 e
951 })?;
952 (Some(single_public_key), None, buf)
953 }
954 OBJECT_PUBLIC_KEY_MN => {
955 let (mn_public_key, buf) = MNPublicKey::raw_decode(buf).map_err(|e| {
956 log::error!(
957 "TypelessObjectDesc::raw_decode_with_context/mn_public_key error:{}",
958 e
959 );
960 e
961 })?;
962 (None, Some(mn_public_key), buf)
963 }
964 _ => {
965 panic!("should not come here");
966 }
967 }
968 } else {
969 (None, None, buf)
970 };
971
972 let buf = if ctx.has_ext() {
974 let (len, buf) = u16::raw_decode(buf).map_err(|e| {
975 error!(
976 "NamedObjectDesc<T>::raw_decode/ext error:{}, obj_type:{}",
977 e, obj_type,
978 );
979 e
980 })?;
981 warn!(
982 "read unknown ext content! len={}, obj_type:{}",
983 len, obj_type
984 );
985
986 if len as usize > buf.len() {
987 let msg = format!(
988 "read unknown ext content but extend buffer limit, obj_type:{}, len={}, buf={}",
989 obj_type,
990 len,
991 buf.len()
992 );
993 error!("{}", msg);
994 return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg));
995 }
996
997 &buf[len as usize..]
998 } else {
999 buf
1000 };
1001
1002 let (version, buf) = u8::raw_decode(buf).map_err(|e| {
1004 error!(
1005 "TypelessObjectDesc::raw_decode/version error:{}, obj_type:{}",
1006 e, obj_type
1007 );
1008 e
1009 })?;
1010
1011 let (format, buf) = u8::raw_decode(buf).map_err(|e| {
1013 error!(
1014 "TypelessObjectDesc::raw_decode/format error:{}, obj_type:{}",
1015 e, obj_type,
1016 );
1017 e
1018 })?;
1019
1020 let (desc_content_len, buf) = u16::raw_decode(buf).map_err(|e| {
1022 log::error!(
1023 "TypelessObjectDesc::raw_decode_with_context/desc_content_len error:{}",
1024 e
1025 );
1026 e
1027 })?;
1028 let size: usize = desc_content_len as usize;
1029
1030 if size > buf.len() {
1031 log::error!("TypelessObjectDesc::raw_decode_with_context/desc_content_len overflow");
1032 return Err(BuckyError::from(BuckyErrorCode::InvalidData));
1033 }
1034
1035 let mut desc_content_buf = vec![0u8; size];
1037 unsafe {
1038 std::ptr::copy(
1039 buf.as_ptr(),
1040 desc_content_buf.as_mut_ptr(),
1041 desc_content_buf.len(),
1042 );
1043 }
1044 let buf = &buf[desc_content_buf.len()..];
1045
1046 Ok((
1048 Self {
1049 obj_type,
1051 dec_id,
1052 ref_objects,
1053 prev,
1054 create_timestamp,
1055 create_time,
1056 expired_time,
1057
1058 owner,
1060 area,
1061 author,
1062 single_public_key,
1063 mn_public_key,
1064
1065 version,
1067 format,
1068
1069 desc_content_len,
1071 desc_content_buf,
1072 },
1073 buf,
1074 ))
1075 }
1076}
1077
1078pub enum TypelessCatagory {
1079 Any = 0,
1080 Standard = 1,
1081 Core = 2,
1082 DECApp = 3,
1083}
1084
1085pub trait TypeCatagoryMark: Clone {
1086 fn catagory() -> TypelessCatagory;
1087}
1088
1089#[derive(Clone, Debug)]
1090pub struct TypelessObjectType<T: TypeCatagoryMark> {
1091 sub_type: Option<PhantomData<T>>,
1092}
1093
1094impl<T: TypeCatagoryMark> ObjectType for TypelessObjectType<T> {
1095 fn obj_type_code() -> ObjectTypeCode {
1096 return ObjectTypeCode::Custom;
1098 }
1099
1100 fn obj_type() -> u16 {
1101 OBJECT_TYPE_ANY
1102 }
1103
1104 type DescType = TypelessObjectDesc;
1105 type ContentType = TypelessObjectBodyContent;
1106}
1107
1108impl<T: TypeCatagoryMark> NamedObjectBase<TypelessObjectType<T>> {
1109 fn convert_to<DescContentT, BodyContentT>(
1112 self,
1113 ) -> BuckyResult<NamedObjectBase<NamedObjType<DescContentT, BodyContentT>>>
1114 where
1115 DescContentT: for<'de> RawDecode<'de> + RawEncode + DescContent + Sync + Send + Clone,
1116 BodyContentT: for<'de> RawDecode<'de> + Sync + Send + Clone + RawEncode + BodyContent,
1117 {
1118 let (desc, body, signs, nonce) = self.split();
1119
1120 assert!(
1122 DescContentT::obj_type() == desc.obj_type()
1123 && DescContentT::obj_type_code() == desc.obj_type_code()
1124 );
1125 if DescContentT::obj_type() != desc.obj_type()
1126 || DescContentT::obj_type_code() != desc.obj_type_code()
1127 {
1128 return Err(BuckyError::new(
1129 BuckyErrorCode::NotMatch,
1130 format!(
1131 "obj_type is not match, require:{}, input:{}",
1132 desc.obj_type(),
1133 DescContentT::obj_type()
1134 ),
1135 ));
1136 }
1137
1138 let typed_desc = desc.convert_to().map_err(|e| {
1139 log::error!(
1140 "NamedObjectBase<TypelessObjectType<T>>::convert_to/typed_desc error:{}",
1141 e
1142 );
1143 e
1144 })?;
1145
1146 let has_body = body.is_some();
1147 if !has_body {
1148 let typed_obj = NamedObjectBase::<NamedObjType<DescContentT, BodyContentT>>::new_desc(
1149 typed_desc, signs, nonce,
1150 );
1151 Ok(typed_obj)
1152 } else {
1153 let (content, update_time, prev_version, user_data) = body.unwrap().split();
1154 let buf = content.data();
1155
1156 let opt = RawDecodeOption {
1158 version: content.version,
1159 format: content.format,
1160 };
1161 let (typed_content, _) =
1162 BodyContentT::raw_decode_with_option(buf, &opt).map_err(|e| {
1163 log::error!(
1164 "NamedObjectBase<TypelessObjectType<T>>::convert_to/typed_content error:{}",
1165 e
1166 );
1167 e
1168 })?;
1169
1170 let body =
1171 ObjectMutBodyBuilder::<BodyContentT, NamedObjType<DescContentT, BodyContentT>>::new(
1172 typed_content,
1173 )
1174 .update_time(update_time)
1175 .option_prev_version(prev_version)
1176 .option_user_data(user_data)
1177 .build();
1178
1179 Ok(
1180 NamedObjectBase::<NamedObjType<DescContentT, BodyContentT>>::new_builder(
1181 typed_desc,
1182 )
1183 .body(body)
1184 .signs(signs)
1185 .option_nonce(nonce)
1186 .build(),
1187 )
1188 }
1189 }
1190
1191 fn convert_to_typeless<M: TypeCatagoryMark>(
1194 self,
1195 ) -> BuckyResult<NamedObjectBase<TypelessObjectType<M>>> {
1196 match M::catagory() {
1198 TypelessCatagory::Any => {
1199 }
1201 TypelessCatagory::Standard => {
1202 assert!(self.desc().is_standard_object());
1203 if !self.desc().is_standard_object() {
1204 return Err(BuckyError::new(
1205 BuckyErrorCode::NotMatch,
1206 format!(
1207 "obj_type is not standard object, obj_type:{}",
1208 self.desc().obj_type()
1209 ),
1210 ));
1211 }
1212 }
1213 TypelessCatagory::Core => {
1214 assert!(self.desc().is_core_object());
1215 if !self.desc().is_core_object() {
1216 return Err(BuckyError::new(
1217 BuckyErrorCode::NotMatch,
1218 format!(
1219 "obj_type is not core object, obj_type:{}",
1220 self.desc().obj_type()
1221 ),
1222 ));
1223 }
1224 }
1225 TypelessCatagory::DECApp => {
1226 assert!(self.desc().is_dec_app_object());
1227 if !self.desc().is_dec_app_object() {
1228 return Err(BuckyError::new(
1229 BuckyErrorCode::NotMatch,
1230 format!(
1231 "obj_type is not dec app object, obj_type:{}",
1232 self.desc().obj_type()
1233 ),
1234 ));
1235 }
1236 }
1237 };
1238
1239 let (desc, body, signs, nonce) = self.split();
1240
1241 let has_body = body.is_some();
1242 if !has_body {
1243 Ok(NamedObjectBase::<TypelessObjectType<M>>::new_desc(
1244 desc, signs, nonce,
1245 ))
1246 } else {
1247 let (content, update_time, prev_version, user_data) = body.unwrap().split();
1248
1249 let body =
1250 ObjectMutBodyBuilder::<TypelessObjectBodyContent, TypelessObjectType<M>>::new(
1251 content,
1252 )
1253 .update_time(update_time)
1254 .option_prev_version(prev_version)
1255 .option_user_data(user_data)
1256 .build();
1257
1258 Ok(NamedObjectBase::<TypelessObjectType<M>>::new_builder(desc)
1259 .body(body)
1260 .signs(signs)
1261 .option_nonce(nonce)
1262 .build())
1263 }
1264 }
1265}
1266
1267impl<T, DescContentT, BodyContentT> TryFrom<NamedObjectBase<TypelessObjectType<T>>>
1269 for NamedObjectBase<NamedObjType<DescContentT, BodyContentT>>
1270where
1271 T: TypeCatagoryMark,
1272 DescContentT: for<'de> RawDecode<'de> + RawEncode + DescContent + Sync + Send + Clone,
1273 BodyContentT: for<'de> RawDecode<'de> + Sync + Send + Clone + RawEncode + BodyContent,
1274{
1275 type Error = BuckyError;
1276 fn try_from(value: NamedObjectBase<TypelessObjectType<T>>) -> Result<Self, Self::Error> {
1277 value.convert_to()
1278 }
1279}
1280
1281impl TryFrom<TypelessAnyObject> for AnyNamedObject {
1283 type Error = BuckyError;
1284 fn try_from(value: TypelessAnyObject) -> Result<Self, Self::Error> {
1285 let obj_type_code = value.desc().obj_type_code();
1286 let obj_type = value.desc().obj_type();
1287 match obj_type_code {
1288 ObjectTypeCode::Device => Ok(AnyNamedObject::Standard(StandardObject::Device(
1289 Device::try_from(value).map_err(|e| {
1290 log::error!("AnyNamedObject::try_from/Device error:{}", e);
1291 e
1292 })?,
1293 ))),
1294 ObjectTypeCode::People => Ok(AnyNamedObject::Standard(StandardObject::People(
1295 People::try_from(value).map_err(|e| {
1296 log::error!("AnyNamedObject::try_from/People error:{}", e);
1297 e
1298 })?,
1299 ))),
1300 ObjectTypeCode::Group => Ok(AnyNamedObject::Standard(StandardObject::Group(
1301 Group::try_from(value).map_err(|e| {
1302 log::error!("AnyNamedObject::try_from/Org error:{}", e);
1303 e
1304 })?,
1305 ))),
1306 ObjectTypeCode::AppGroup => Ok(AnyNamedObject::Standard(StandardObject::AppGroup(
1307 AppGroup::try_from(value).map_err(|e| {
1308 log::error!("AnyNamedObject::try_from/AppGroup error:{}", e);
1309 e
1310 })?,
1311 ))),
1312 ObjectTypeCode::UnionAccount => Ok(AnyNamedObject::Standard(
1313 StandardObject::UnionAccount(UnionAccount::try_from(value).map_err(|e| {
1314 log::error!("AnyNamedObject::try_from/UnionAccount error:{}", e);
1315 e
1316 })?),
1317 )),
1318 ObjectTypeCode::Chunk => {
1319 unreachable!();
1320 }
1321 ObjectTypeCode::File => Ok(AnyNamedObject::Standard(StandardObject::File(
1322 File::try_from(value).map_err(|e| {
1323 log::error!("AnyNamedObject::try_from/File error:{}", e);
1324 e
1325 })?,
1326 ))),
1327 ObjectTypeCode::Dir => Ok(AnyNamedObject::Standard(StandardObject::Dir(
1328 Dir::try_from(value).map_err(|e| {
1329 log::error!("AnyNamedObject::try_from/Dir error:{}", e);
1330 e
1331 })?,
1332 ))),
1333 ObjectTypeCode::Diff => Ok(AnyNamedObject::Standard(StandardObject::Diff(
1334 Diff::try_from(value).map_err(|e| {
1335 log::error!("AnyNamedObject::try_from/Diff error:{}", e);
1336 e
1337 })?,
1338 ))),
1339 ObjectTypeCode::ProofOfService => Ok(AnyNamedObject::Standard(
1340 StandardObject::ProofOfService(ProofOfService::try_from(value).map_err(|e| {
1341 log::error!("AnyNamedObject::try_from/ProofOfService error:{}", e);
1342 e
1343 })?),
1344 )),
1345 ObjectTypeCode::Tx => Ok(AnyNamedObject::Standard(StandardObject::Tx(
1346 Tx::try_from(value).map_err(|e| {
1347 log::error!("AnyNamedObject::try_from/Tx error:{}", e);
1348 e
1349 })?,
1350 ))),
1351 ObjectTypeCode::Action => Ok(AnyNamedObject::Standard(StandardObject::Action(
1352 Action::try_from(value).map_err(|e| {
1353 log::error!("AnyNamedObject::try_from/Action error:{}", e);
1354 e
1355 })?,
1356 ))),
1357 ObjectTypeCode::ObjectMap => Ok(AnyNamedObject::Standard(StandardObject::ObjectMap(
1358 ObjectMap::try_from(value).map_err(|e| {
1359 log::error!("AnyNamedObject::try_from/ObjectMap error:{}", e);
1360 e
1361 })?,
1362 ))),
1363 ObjectTypeCode::Contract => Ok(AnyNamedObject::Standard(StandardObject::Contract(
1364 Contract::try_from(value).map_err(|e| {
1365 log::error!("AnyNamedObject::try_from/Contract error:{}", e);
1366 e
1367 })?,
1368 ))),
1369 ObjectTypeCode::Custom => {
1370 assert!(object_type_helper::is_custom_object(obj_type));
1371
1372 if object_type_helper::is_core_object(obj_type) {
1373 Ok(AnyNamedObject::Core(
1374 value.convert_to_typeless::<CoreTypeMark>().map_err(|e| {
1375 log::error!("AnyNamedObject::try_from/Core error:{}", e);
1376 e
1377 })?,
1378 ))
1379 } else {
1380 Ok(AnyNamedObject::DECApp(
1381 value.convert_to_typeless::<DECAppTypeMark>().map_err(|e| {
1382 log::error!("AnyNamedObject::try_from/DECApp error:{}", e);
1383 e
1384 })?,
1385 ))
1386 }
1387 }
1388 }
1389 }
1390}
1391
1392#[derive(Clone)]
1397pub struct AnyTypeMark {}
1398
1399impl TypeCatagoryMark for AnyTypeMark {
1400 fn catagory() -> TypelessCatagory {
1401 TypelessCatagory::Any
1402 }
1403}
1404
1405#[derive(Clone, Debug)]
1417pub struct CoreTypeMark {}
1418
1419impl TypeCatagoryMark for CoreTypeMark {
1420 fn catagory() -> TypelessCatagory {
1421 TypelessCatagory::Core
1422 }
1423}
1424
1425#[derive(Clone, Debug)]
1426pub struct DECAppTypeMark {}
1427
1428impl TypeCatagoryMark for DECAppTypeMark {
1429 fn catagory() -> TypelessCatagory {
1430 TypelessCatagory::DECApp
1431 }
1432}
1433
1434pub type TypelessAnyObject = NamedObjectBase<TypelessObjectType<AnyTypeMark>>;
1435pub type TypelessCoreObject = NamedObjectBase<TypelessObjectType<CoreTypeMark>>;
1437pub type TypelessDECAppObject = NamedObjectBase<TypelessObjectType<DECAppTypeMark>>;
1438
1439#[derive(RawEncode, RawDecode, Clone)]
1444struct ExtDescContent {
1445 to: PeopleId,
1446}
1447
1448impl DescContent for ExtDescContent {
1449 fn obj_type() -> u16 {
1450 17u16
1451 }
1452 type OwnerType = Option<ObjectId>;
1453 type AreaType = SubDescNone;
1454 type AuthorType = Option<ObjectId>;
1455 type PublicKeyType = SubDescNone;
1456}
1457
1458#[derive(RawEncode, RawDecode, Clone)]
1459struct ExtBodyContent {}
1460
1461impl BodyContent for ExtBodyContent {}
1462
1463type ExtType = NamedObjType<ExtDescContent, ExtBodyContent>;
1464type ExtBuilder = NamedObjectBuilder<ExtDescContent, ExtBodyContent>;
1465
1466type ExtDesc = NamedObjectDesc<ExtDescContent>;
1467type ExtId = NamedObjectId<ExtType>;
1468type Ext = NamedObjectBase<ExtType>;
1469
1470trait ExtObjectDesc {
1471 fn ext_id(&self) -> ExtId;
1472}
1473
1474trait ExtObject {
1475 fn new(owner: &PeopleId, author: &ObjectId, to: PeopleId) -> ExtBuilder;
1476 fn to(&self) -> &PeopleId;
1477}
1478
1479impl ExtObjectDesc for ExtDesc {
1480 fn ext_id(&self) -> ExtId {
1481 ExtId::try_from(self.calculate_id()).unwrap()
1482 }
1483}
1484
1485impl ExtObject for Ext {
1486 fn new(owner: &PeopleId, author: &ObjectId, to: PeopleId) -> ExtBuilder {
1487 let desc_content = ExtDescContent { to };
1488
1489 let body_content = ExtBodyContent {};
1490 ExtBuilder::new(desc_content, body_content)
1491 .owner(owner.object_id().clone())
1492 .author(author.clone())
1493 }
1494
1495 fn to(&self) -> &PeopleId {
1496 &self.desc().content().to
1497 }
1498}
1499
1500#[cfg(test)]
1501mod test {
1502 use crate::{NamedObject, ObjectId, PeopleId, RawConvertTo, RawFrom};
1503
1504 use super::{
1505 Ext, ExtBodyContent, ExtDescContent, ExtObject, ExtObjectDesc, ObjectDesc,
1506 TypelessCoreObject,
1507 };
1508
1509 #[test]
1510 fn typeless() {
1511 let owner = PeopleId::default();
1512 let author = ObjectId::default();
1513 let to = PeopleId::default();
1514 let ext = Ext::new(&owner, &author, to).no_create_time().build();
1515 let buf = ext.to_vec().unwrap();
1516 println!("\n\n");
1517
1518 let obj_decode_from_typed = Ext::clone_from_slice(&buf).unwrap();
1519 println!("\n\n");
1520
1521 let type_less_ext = TypelessCoreObject::clone_from_slice(&buf).unwrap();
1522 println!("\n\n");
1523
1524 let buf = type_less_ext.to_vec().unwrap();
1525 println!("\n\n");
1526
1527 let type_less_ext_2 = TypelessCoreObject::clone_from_slice(&buf).unwrap();
1528 assert!(type_less_ext_2.desc().calculate_id() == type_less_ext.desc().calculate_id());
1529 println!("\n\n");
1530
1531 let obj_decode_from_typeless = Ext::clone_from_slice(&buf).unwrap();
1534 println!("\n\n");
1535
1536 let id_decode_from_typed = obj_decode_from_typed.desc().ext_id();
1537 let id_decode_from_typeless = obj_decode_from_typeless.desc().ext_id();
1538
1539 println!("\n\nid_decode_from_typed:{}\n\n", id_decode_from_typed);
1540 println!(
1541 "\n\nid_decode_from_typeless:{}\n\n",
1542 id_decode_from_typeless
1543 );
1544
1545 assert!(id_decode_from_typed == id_decode_from_typeless);
1546
1547 let obj_convert_from_typeless = type_less_ext
1548 .convert_to::<ExtDescContent, ExtBodyContent>()
1549 .unwrap();
1550 println!("\n\n");
1551
1552 let id_convert_from_typeless = obj_convert_from_typeless.desc().ext_id();
1553 println!("\n\n");
1554
1555 println!("\n\nid_decode_from_typed:{}\n\n", id_decode_from_typed);
1556 println!(
1557 "\n\nid_convert_from_typeless:{}\n\n",
1558 id_convert_from_typeless
1559 );
1560
1561 assert!(id_decode_from_typed == id_convert_from_typeless);
1562 }
1563}