bucky_objects/objects/
object_typeless.rs

1use crate::*;
2
3use std::convert::TryFrom;
4use std::marker::PhantomData;
5
6#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
7pub struct TypelessObjectBodyContent {
8    // body_content关联的version和format
9    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        // 外层在编解码body_content时候,会保证此值
54        assert!(buf.len() >= len);
55
56        // Buffer
57        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        // 外部传入的buf长度就是body_content的真正长度
77        let size = buf.len();
78
79        // Buffer
80        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/// 无类型的Buffer对象,丢失了SubDesc和DescContent部分的类型信息
98/// 实际上也是可以做到带组合类型信息,不过Owner x Area x Author x PublicKey 一共有 24 种组合类型
99/// 不过,既然丢失了类型信息,只提供组合类型信息也只是完成了类型信息的一半,
100/// 可以通过提供build的方式重建具体的带类型信息的NamedObject,通过调用者注入具体的类型信息完成完整的重构
101#[derive(Clone, Debug)]
102pub struct TypelessObjectDesc {
103    // 基本部分 ObjectDesc
104    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    // 丢失了原始类型信息,但是可以获取
112    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    // desc_content对应的version和format
119    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
169/// 丢失了SubDesc类型信息,用成员方法的方式暴露是否含有这些数据
170impl 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        // 必须使用带version和format的decode解码
200        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
265/// TypelessObjectDesc 用于计算ID用的编码
266/// ===
267/// * [1] ctx 部分包含obj_type, obj_flags 信息(前5bits为0,区别于NamedObject里的ctx.obj_flags)
268/// * [2] 其余部分为desc本身的编码
269impl 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            // assert!(left_buf.len() == 0);
350        }
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            // assert!(left_buf.len() == 0);
383        }
384
385        Ok(buf)
386    }
387}
388
389/// TypelessObjectDesc 编码
390/// ===
391/// * [1] ctx 部分来自NamedObject里的ctx
392/// * [2] 其余部分为desc本身的编码
393impl RawEncodeWithContext<NamedObjectContext> for TypelessObjectDesc {
394    fn raw_measure_with_context(
395        &self,
396        ctx: &mut NamedObjectContext,
397        purpose: &Option<RawEncodePurpose>,
398    ) -> BuckyResult<usize> {
399        // obj_type 和 obj_flags在NamedObject上层编解码,此处把相关信息通过ctx传递给上层
400        let mut size = 0;
401
402        //
403        // ObjectDesc
404        //
405
406        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        //
485        // OwnderObjectDesc/AreaObjectDesc/AuthorObjectDesc/PublicKeyObjectDesc
486        //
487
488        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        // version+formmat
574        size += u16::raw_bytes().unwrap();
575
576        // desc_content
577        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        // ObjectDesc
590        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            //
749        }
750
751        // 编码version, 8bits
752        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        // 编码format, 8bits
762        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        // desc_content_len
772        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        // desc_content_buf
784        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
797/// TypelessObjectDesc 解码
798/// ===
799/// * [1] ctx 部分来自NamedObject里的ctx
800/// * [2] 其余部分为desc本身的解码
801impl<'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        //
809        // ObjectDesc
810        //
811
812        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        //
897        // OwnderObjectDesc/AreaObjectDesc/AuthorObjectDesc/PublicKeyObjectDesc
898        //
899        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        // 预留的扩展字段
973        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        // version
1003        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        // format
1012        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        // len+desc_content
1021        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        // desc_content_buf
1036        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        // panic!("2");
1047        Ok((
1048            Self {
1049                // ObjectDesc
1050                obj_type,
1051                dec_id,
1052                ref_objects,
1053                prev,
1054                create_timestamp,
1055                create_time,
1056                expired_time,
1057
1058                // OwnderObjectDesc/AreaObjectDesc/AuthorObjectDesc/PublicKeyObjectDesc
1059                owner,
1060                area,
1061                author,
1062                single_public_key,
1063                mn_public_key,
1064
1065                // version+format
1066                version,
1067                format,
1068
1069                // desc_content
1070                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        // panic!("should not come here");
1097        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    // 转成强类型对象
1110    // 运行时类型匹配检查
1111    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        // 运行时类型匹配检查
1121        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            // 这里需要使用解码出来的version+format进行二次解析
1157            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    // 脱壳,强转成另外一种类型
1192    // 运行时类型匹配检查
1193    fn convert_to_typeless<M: TypeCatagoryMark>(
1194        self,
1195    ) -> BuckyResult<NamedObjectBase<TypelessObjectType<M>>> {
1196        // 运行时类型匹配检查
1197        match M::catagory() {
1198            TypelessCatagory::Any => {
1199                // ignore
1200            }
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
1267/// 从 TypelessAnyObject/TypelessCoreObject/TypelessStandardObject/TypelessDECAppObject 转成 具体的强类型
1268impl<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
1281/// 从 TypelessAnyObject 转成 AnyNamedObject
1282impl 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// TODO: 提供从具体的强类型转成 TypelessXXXObject的转换
1393// 直接通过 RawEncode/RawDecode 也可以,但是会多一些消耗,
1394// 通过split的话,只需要对desc_content/body_content部分做RawEncode, 所以还是有价值的
1395
1396#[derive(Clone)]
1397pub struct AnyTypeMark {}
1398
1399impl TypeCatagoryMark for AnyTypeMark {
1400    fn catagory() -> TypelessCatagory {
1401        TypelessCatagory::Any
1402    }
1403}
1404
1405// #[derive(Clone)]
1406// pub struct StandardTypeMark{
1407
1408// }
1409
1410// impl TypeCatagoryMark for StandardTypeMark {
1411//     fn catagory()->TypelessCatagory{
1412//         TypelessCatagory::Standard
1413//     }
1414// }
1415
1416#[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>>;
1435// pub type TypelessStandardObject = NamedObjectBase<TypelessObjectType<StandardTypeMark>>;
1436pub type TypelessCoreObject = NamedObjectBase<TypelessObjectType<CoreTypeMark>>;
1437pub type TypelessDECAppObject = NamedObjectBase<TypelessObjectType<DECAppTypeMark>>;
1438
1439// -------------------------------
1440// 示例 扩展对象
1441//-------------------------------
1442
1443#[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        //
1532
1533        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}