bucky_objects/objects/
any.rs

1use crate::*;
2
3#[derive(Debug, Clone)]
4pub enum AnyNamedObject {
5    Standard(StandardObject),
6    Core(TypelessCoreObject),
7    DECApp(TypelessDECAppObject),
8}
9
10#[macro_export]
11macro_rules! match_any_obj {
12    ($on:ident, $o:ident, $body:tt, $chunk_id:ident, $chunk_body:tt) => {
13        match $on {
14            AnyNamedObject::Standard(o) => match o {
15                StandardObject::Device($o) => $body,
16                StandardObject::People($o) => $body,
17                StandardObject::Group($o) => $body,
18                StandardObject::AppGroup($o) => $body,
19                StandardObject::UnionAccount($o) => $body,
20                StandardObject::ChunkId($chunk_id) => $chunk_body,
21                StandardObject::File($o) => $body,
22                StandardObject::Dir($o) => $body,
23                StandardObject::Diff($o) => $body,
24                StandardObject::ProofOfService($o) => $body,
25                StandardObject::Tx($o) => $body,
26                StandardObject::Action($o) => $body,
27                StandardObject::ObjectMap($o) => $body,
28                StandardObject::Contract($o) => $body,
29            },
30            AnyNamedObject::Core($o) => $body,
31            AnyNamedObject::DECApp($o) => $body,
32        }
33    };
34}
35
36impl AnyNamedObject {
37    pub fn object_id(&self) -> ObjectId {
38        self.calculate_id()
39    }
40    pub fn calculate_id(&self) -> ObjectId {
41        match_any_obj!(self, o, { o.desc().calculate_id() }, chunk_id, {
42            chunk_id.object_id()
43        })
44    }
45
46    pub fn try_clone(&self) -> BuckyResult<Self> {
47        let len = self.raw_measure(&None).map_err(|e| {
48            log::error!("AnyNamedObject::try_clone/raw_measure error:{}", e);
49            e
50        })?;
51
52        let mut buf = Vec::with_capacity(len);
53        unsafe {
54            buf.set_len(len);
55        }
56
57        self.raw_encode(&mut buf[..], &None).map_err(|e| {
58            log::error!("AnyNamedObject::try_clone/raw_encode error:{}", e);
59            e
60        })?;
61
62        let (ret, _) = Self::raw_decode(&buf[..]).map_err(|e| {
63            log::error!("AnyNamedObject::try_clone/raw_decode error:{}", e);
64            e
65        })?;
66
67        Ok(ret)
68    }
69
70    pub fn obj_type(&self) -> u16 {
71        match_any_obj!(self, o, { o.desc().obj_type() }, _chunk_id, {
72            ObjectTypeCode::Chunk.to_u16()
73        })
74    }
75
76    pub fn obj_type_code(&self) -> ObjectTypeCode {
77        match_any_obj!(self, o, { o.desc().obj_type_code() }, _chunk_id, {
78            ObjectTypeCode::Chunk
79        })
80    }
81
82    pub fn dec_id(&self) -> &Option<ObjectId> {
83        match_any_obj!(self, o, { o.desc().dec_id() }, _chunk_id, { &None })
84    }
85
86    pub fn owner(&self) -> &Option<ObjectId> {
87        match self {
88            AnyNamedObject::Standard(s) => s.owner(),
89            AnyNamedObject::Core(c) => c.desc().owner(),
90            AnyNamedObject::DECApp(d) => d.desc().owner(),
91        }
92    }
93
94    pub fn public_key(&self) -> Option<PublicKeyRef> {
95        match self {
96            AnyNamedObject::Standard(s) => s.public_key(),
97            AnyNamedObject::Core(o) => o.desc().public_key(),
98            AnyNamedObject::DECApp(o) => o.desc().public_key(),
99        }
100    }
101
102    pub fn author(&self) -> &Option<ObjectId> {
103        match self {
104            AnyNamedObject::Standard(s) => s.author(),
105            AnyNamedObject::Core(c) => c.desc().author(),
106            AnyNamedObject::DECApp(d) => d.desc().author(),
107        }
108    }
109
110    pub fn prev(&self) -> &Option<ObjectId> {
111        match self {
112            AnyNamedObject::Standard(s) => s.prev(),
113            AnyNamedObject::Core(c) => c.desc().prev(),
114            AnyNamedObject::DECApp(d) => d.desc().prev(),
115        }
116    }
117
118    pub fn ood_list(&self) -> BuckyResult<&Vec<DeviceId>> {
119        match self {
120            AnyNamedObject::Standard(s) => s.ood_list(),
121            AnyNamedObject::Core(_c) => Err(BuckyError::new(
122                BuckyErrorCode::NotSupport,
123                "ood_list not support in typeless Core object",
124            )),
125            AnyNamedObject::DECApp(_d) => Err(BuckyError::new(
126                BuckyErrorCode::NotSupport,
127                "ood_list not support in typeless DECApp object",
128            )),
129        }
130    }
131
132    pub fn ood_work_mode(&self) -> BuckyResult<OODWorkMode> {
133        match self {
134            AnyNamedObject::Standard(s) => s.ood_work_mode(),
135            AnyNamedObject::Core(_c) => Err(BuckyError::new(
136                BuckyErrorCode::NotSupport,
137                "ood_work_mode not support in typeless Core object",
138            )),
139            AnyNamedObject::DECApp(_d) => Err(BuckyError::new(
140                BuckyErrorCode::NotSupport,
141                "ood_work_mode not support in typeless DECApp object",
142            )),
143        }
144    }
145
146    pub fn signs(&self) -> Option<&ObjectSigns> {
147        match_any_obj!(self, o, { Some(o.signs()) }, chunk_id, {
148            error!("chunk has no signs: {}", chunk_id);
149
150            None
151        })
152    }
153
154    pub fn signs_mut(&mut self) -> Option<&mut ObjectSigns> {
155        match_any_obj!(self, o, { Some(o.signs_mut()) }, chunk_id, {
156            error!("chunk has no signs: {}", chunk_id);
157
158            None
159        })
160    }
161
162    pub fn desc_hash(&self) -> BuckyResult<HashValue> {
163        match_any_obj!(self, o, { o.desc().raw_hash_value() }, chunk_id, {
164            let msg = format!("chunk has no desc: {}", chunk_id);
165            error!("{}", msg);
166            Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
167        })
168    }
169
170    pub fn has_body(&self) -> BuckyResult<bool> {
171        match_any_obj!(self, o, { Ok(o.body().is_some()) }, chunk_id, {
172            let msg = format!("chunk has no body: {}", chunk_id);
173            error!("{}", msg);
174            Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
175        })
176    }
177
178    pub fn body_hash(&self) -> BuckyResult<Option<HashValue>> {
179        match_any_obj!(
180            self,
181            o,
182            {
183                if o.body().is_some() {
184                    let hash_value = o.body().as_ref().unwrap().raw_hash_value()?;
185                    Ok(Some(hash_value))
186                } else {
187                    Ok(None)
188                }
189            },
190            chunk_id,
191            {
192                let msg = format!("chunk has no body: {}", chunk_id);
193                error!("{}", msg);
194                Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
195            }
196        )
197    }
198
199    pub fn body_object_id(&self) -> &Option<ObjectId> {
200        match_any_obj!(
201            self,
202            o,
203            {
204                if let Some(body) = o.body() {
205                    body.object_id()
206                } else {
207                    &None
208                }
209            },
210            _chunk_id,
211            { &None }
212        )
213    }
214
215    pub fn verify_body_object_id(&self, object_id: &ObjectId) -> BuckyResult<()> {
216        match_any_obj!(
217            self,
218            o,
219            {
220                if let Some(body) = o.body() {
221                    body.verify_object_id(object_id)
222                } else {
223                    let msg = format!("object has no body: {}", self.calculate_id());
224                    error!("{}", msg);
225                    Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
226                }
227            },
228            chunk_id,
229            {
230                let msg = format!("chunk has no body: {}", chunk_id);
231                error!("{}", msg);
232                Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
233            }
234        )
235    }
236
237    pub fn body_prev_version(&self) -> &Option<HashValue> {
238        match_any_obj!(
239            self,
240            o,
241            {
242                if let Some(body) = o.body() {
243                    let hash_value = body.prev_version();
244                    hash_value
245                } else {
246                    &None
247                }
248            },
249            _chunk_id,
250            { &None }
251        )
252    }
253
254    pub fn ref_objs(&self) -> Option<&Vec<ObjectLink>> {
255        match_any_obj!(self, o, { o.desc().ref_objs().as_ref() }, chunk_id, {
256            error!("chunk has no ref_objs: {}", chunk_id);
257
258            None
259        })
260    }
261
262    pub fn is_standard(&self) -> bool {
263        match self {
264            AnyNamedObject::Standard(_) => true,
265            _ => false,
266        }
267    }
268
269    pub fn is_core(&self) -> bool {
270        match self {
271            AnyNamedObject::Core(_) => true,
272            _ => false,
273        }
274    }
275
276    pub fn is_dec(&self) -> bool {
277        match self {
278            AnyNamedObject::DECApp(_) => true,
279            _ => false,
280        }
281    }
282
283    // reset the object's body with the same obj_type object
284    pub fn set_body_expect(&mut self, other: &Self) {
285        assert_eq!(self.obj_type(), other.obj_type());
286
287        match self {
288            Self::Standard(o) => match other {
289                Self::Standard(other) => {
290                    o.set_body_expect(other);
291                }
292                _ => unreachable!(),
293            },
294            Self::Core(o) => match other {
295                Self::Core(other) => {
296                    *o.body_mut() = other.body().to_owned();
297                }
298                _ => unreachable!(),
299            },
300            Self::DECApp(o) => match other {
301                Self::DECApp(other) => {
302                    *o.body_mut() = other.body().to_owned();
303                }
304                _ => unreachable!(),
305            },
306        }
307    }
308
309    // 设置对象body的修改时间
310    pub fn set_body_update_time(&mut self, time: u64) {
311        match_any_obj!(
312            self,
313            o,
314            {
315                match o.body_mut().as_mut() {
316                    Some(body) => body.set_update_time(time),
317                    None => {}
318                }
319            },
320            _chunk_id,
321            {}
322        )
323    }
324
325    pub fn create_time(&self) -> u64 {
326        match_any_obj!(self, o, { o.desc().create_time() }, _chunk_id, { 0 })
327    }
328
329    pub fn option_create_time(&self) -> Option<u64> {
330        match_any_obj!(self, o, { o.desc().option_create_time() }, _chunk_id, {
331            None
332        })
333    }
334
335    pub fn expired_time(&self) -> Option<u64> {
336        match_any_obj!(self, o, { o.desc().expired_time() }, _chunk_id, { None })
337    }
338
339    pub fn update_time(&self) -> Option<u64> {
340        match_any_obj!(
341            self,
342            o,
343            {
344                match o.body().as_ref() {
345                    Some(body) => Some(body.update_time()),
346                    None => None,
347                }
348            },
349            _chunk_id,
350            { None }
351        )
352    }
353
354    // 获取对象body的修改时间(不包括签名)
355    pub fn get_update_time(&self) -> u64 {
356        match_any_obj!(
357            self,
358            o,
359            {
360                match o.body().as_ref() {
361                    Some(body) => body.update_time(),
362                    None => 0_u64,
363                }
364            },
365            _chunk_id,
366            { 0 }
367        )
368    }
369
370    // Get the latest modification time of body+signs
371    pub fn get_full_update_time(&self) -> u64 {
372        let update_time = self.get_update_time();
373
374        // If the signature time is relatively new, then take the signature time
375        let latest_sign_time = match self.signs() {
376            Some(v) => v.latest_sign_time(),
377            None => 0,
378        };
379
380        std::cmp::max(update_time, latest_sign_time)
381    }
382
383    pub fn nonce(&self) -> &Option<u128> {
384        match_any_obj!(self, o, { o.nonce() }, _chunk_id, { &None })
385    }
386
387    fn raw_decode_device<'de>(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
388        let (device, buf) = Device::raw_decode(buf).map_err(|e| {
389            log::error!("AnyNamedObject::raw_decode/device error:{}", e);
390            e
391        })?;
392        Ok((
393            AnyNamedObject::Standard(StandardObject::Device(device)),
394            buf,
395        ))
396    }
397
398    fn raw_decode_people<'de>(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
399        let (people, buf) = People::raw_decode(buf).map_err(|e| {
400            log::error!("AnyNamedObject::raw_decode/people error:{}", e);
401            e
402        })?;
403        Ok((
404            AnyNamedObject::Standard(StandardObject::People(people)),
405            buf,
406        ))
407    }
408
409    fn raw_decode_app_group<'de>(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
410        let (app_group, buf) = AppGroup::raw_decode(buf).map_err(|e| {
411            log::error!("AnyNamedObject::raw_decode/app_group error:{}", e);
412            e
413        })?;
414        Ok((
415            AnyNamedObject::Standard(StandardObject::AppGroup(app_group)),
416            buf,
417        ))
418    }
419
420    fn raw_decode_group<'de>(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
421        let (simple_group, buf) = Group::raw_decode(buf).map_err(|e| {
422            log::error!("AnyNamedObject::raw_decode/group error:{}", e);
423            e
424        })?;
425        return Ok((
426            AnyNamedObject::Standard(StandardObject::Group(simple_group)),
427            buf,
428        ));
429    }
430
431    fn raw_decode_union_account<'de>(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
432        let (ua, buf) = UnionAccount::raw_decode(buf).map_err(|e| {
433            log::error!("AnyNamedObject::raw_decode/ua error:{}", e);
434            e
435        })?;
436        Ok((
437            AnyNamedObject::Standard(StandardObject::UnionAccount(ua)),
438            buf,
439        ))
440    }
441
442    fn raw_decode_file<'de>(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
443        let (file, buf) = File::raw_decode(buf).map_err(|e| {
444            log::error!("AnyNamedObject::raw_decode/file error:{}", e);
445            e
446        })?;
447        Ok((AnyNamedObject::Standard(StandardObject::File(file)), buf))
448    }
449
450    fn raw_decode_dir<'de>(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
451        let (dir, buf) = Dir::raw_decode(buf).map_err(|e| {
452            log::error!("AnyNamedObject::raw_decode/dir error:{}", e);
453            e
454        })?;
455        Ok((AnyNamedObject::Standard(StandardObject::Dir(dir)), buf))
456    }
457
458    fn raw_decode_diff<'de>(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
459        let (diff, buf) = Diff::raw_decode(buf).map_err(|e| {
460            log::error!("AnyNamedObject::raw_decode/diff error:{}", e);
461            e
462        })?;
463        Ok((AnyNamedObject::Standard(StandardObject::Diff(diff)), buf))
464    }
465
466    fn raw_decode_proof_of_service<'de>(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
467        let (prof, buf) = ProofOfService::raw_decode(buf).map_err(|e| {
468            log::error!("AnyNamedObject::raw_decode/prof error:{}", e);
469            e
470        })?;
471        Ok((
472            AnyNamedObject::Standard(StandardObject::ProofOfService(prof)),
473            buf,
474        ))
475    }
476
477    fn raw_decode_tx<'de>(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
478        let (tx, buf) = Tx::raw_decode(buf).map_err(|e| {
479            log::error!("AnyNamedObject::raw_decode/tx error:{}", e);
480            e
481        })?;
482        Ok((AnyNamedObject::Standard(StandardObject::Tx(tx)), buf))
483    }
484
485    fn raw_decode_action<'de>(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
486        let (action, buf) = Action::raw_decode(buf).map_err(|e| {
487            log::error!("AnyNamedObject::raw_decode/action error:{}", e);
488            e
489        })?;
490        Ok((
491            AnyNamedObject::Standard(StandardObject::Action(action)),
492            buf,
493        ))
494    }
495
496    fn raw_decode_object_map<'de>(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
497        let (relation, buf) = ObjectMap::raw_decode(buf).map_err(|e| {
498            log::error!("AnyNamedObject::raw_decode/relation error:{}", e);
499            e
500        })?;
501        Ok((
502            AnyNamedObject::Standard(StandardObject::ObjectMap(relation)),
503            buf,
504        ))
505    }
506
507    fn raw_decode_contract<'de>(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
508        let (contract, buf) = Contract::raw_decode(buf).map_err(|e| {
509            log::error!("AnyNamedObject::raw_decode/contract error:{}", e);
510            e
511        })?;
512        Ok((
513            AnyNamedObject::Standard(StandardObject::Contract(contract)),
514            buf,
515        ))
516    }
517
518    fn raw_decode_custom<'de>(
519        buf: &'de [u8],
520        is_dec_app_object: bool,
521    ) -> Result<(Self, &'de [u8]), BuckyError> {
522        if is_dec_app_object {
523            // println!("is dec app object");
524
525            let (dec_obj, buf) = TypelessDECAppObject::raw_decode(buf)?;
526            Ok((AnyNamedObject::DECApp(dec_obj), buf))
527        } else {
528            // println!("is core object");
529
530            let (core_obj, buf) = TypelessCoreObject::raw_decode(buf)?;
531            Ok((AnyNamedObject::Core(core_obj), buf))
532        }
533    }
534}
535
536impl RawEncode for AnyNamedObject {
537    fn raw_measure(&self, purpose: &Option<RawEncodePurpose>) -> BuckyResult<usize> {
538        match self {
539            AnyNamedObject::Standard(obj) => obj.raw_measure(purpose),
540            AnyNamedObject::Core(obj) => obj.raw_measure(purpose),
541            AnyNamedObject::DECApp(obj) => obj.raw_measure(purpose),
542        }
543    }
544
545    fn raw_encode<'a>(
546        &self,
547        buf: &'a mut [u8],
548        purpose: &Option<RawEncodePurpose>,
549    ) -> BuckyResult<&'a mut [u8]> {
550        match self {
551            AnyNamedObject::Standard(obj) => obj.raw_encode(buf, purpose),
552            AnyNamedObject::Core(obj) => obj.raw_encode(buf, purpose),
553            AnyNamedObject::DECApp(obj) => obj.raw_encode(buf, purpose),
554        }
555    }
556}
557
558impl<'de> RawDecode<'de> for AnyNamedObject {
559    fn raw_decode(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
560        let (obj_type_info, _new_buffer) = NamedObjectContext::raw_decode(buf).map_err(|e| {
561            log::error!("AnyNamedObject::raw_decode/obj_type_info error:{}", e);
562            e
563        })?;
564
565        match obj_type_info.obj_type_code() {
566            ObjectTypeCode::Device => Self::raw_decode_device(buf),
567            ObjectTypeCode::People => Self::raw_decode_people(buf),
568            ObjectTypeCode::AppGroup => Self::raw_decode_app_group(buf),
569            ObjectTypeCode::UnionAccount => Self::raw_decode_union_account(buf),
570            ObjectTypeCode::Chunk => {
571                unreachable!();
572            }
573            ObjectTypeCode::File => Self::raw_decode_file(buf),
574            ObjectTypeCode::Dir => Self::raw_decode_dir(buf),
575            ObjectTypeCode::Diff => Self::raw_decode_diff(buf),
576            ObjectTypeCode::ProofOfService => Self::raw_decode_proof_of_service(buf),
577            ObjectTypeCode::Tx => Self::raw_decode_tx(buf),
578            ObjectTypeCode::Action => Self::raw_decode_action(buf),
579            ObjectTypeCode::ObjectMap => Self::raw_decode_object_map(buf),
580            ObjectTypeCode::Contract => Self::raw_decode_contract(buf),
581            ObjectTypeCode::Custom => {
582                Self::raw_decode_custom(buf, obj_type_info.is_decapp_object())
583            }
584            ObjectTypeCode::Group => Self::raw_decode_group(buf),
585        }
586    }
587}
588
589// 用 base16 hex实现serde
590use serde::{
591    de::{self, Visitor},
592    Deserialize, Deserializer, Serialize, Serializer,
593};
594
595impl Serialize for AnyNamedObject {
596    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
597    where
598        S: Serializer,
599    {
600        let len = self.raw_measure(&None).unwrap();
601        let mut buf = vec![0u8; len];
602        self.raw_encode(buf.as_mut_slice(), &None).unwrap();
603        serializer.serialize_str(&hex::encode(buf))
604    }
605}
606
607impl<'de> Deserialize<'de> for AnyNamedObject {
608    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
609    where
610        D: Deserializer<'de>,
611    {
612        struct RawObjectIdVisitor;
613        impl<'de> Visitor<'de> for RawObjectIdVisitor {
614            type Value = AnyNamedObject;
615            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
616                write!(formatter, "{}", "an ObjectId")
617            }
618            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
619            where
620                E: de::Error,
621            {
622                let raw = hex::decode(v)
623                    .map_err(|err| E::custom(err.to_string()))
624                    .map_err(|e| {
625                        log::error!("AnyNamedObject::Deserialize error:{}", e);
626                        e
627                    })?;
628                AnyNamedObject::raw_decode(raw.as_slice())
629                    .map_err(|err| E::custom(err.to_string()))
630                    .map(|(obj, _)| obj)
631            }
632        }
633        deserializer.deserialize_str(RawObjectIdVisitor)
634    }
635}
636
637use std::sync::Arc;
638impl Into<AnyNamedObject> for Arc<AnyNamedObject> {
639    fn into(self) -> AnyNamedObject {
640        match Arc::try_unwrap(self) {
641            Ok(v) => v,
642            Err(v) => v.as_ref().clone(),
643        }
644    }
645}
646
647#[cfg(test)]
648mod tests {
649    use crate::*;
650    use std::str::FromStr;
651
652    #[test]
653    fn test_any() {
654        let mut sn_list = Vec::new();
655        let mut endpoints = Vec::new();
656        let unique_id = UniqueId::default();
657        let name = "test_device";
658        let owner = ObjectId::from_str("5aSixgLtjoYcAFH9isc6KCqDgKfTJ8jpgASAoiRz5NLk").unwrap();
659
660        let ep = Endpoint::from_str("W4udp120.24.6.201:8060").unwrap();
661        for _ in 0..10 {
662            endpoints.push(ep.clone());
663        }
664        let device_id2 =
665            DeviceId::from_str("5aSixgPXvhR4puWzFCHqvUXrjFWjxbq4y3thJVgZg6ty").unwrap();
666        for _ in 0..10 {
667            sn_list.push(device_id2.clone());
668        }
669        let desc_content = DeviceDescContent::new(unique_id.clone());
670
671        let body_content =
672            DeviceBodyContent::new(endpoints, sn_list, Vec::new(), Some(name.to_owned()), None);
673        let secret1 = PrivateKey::generate_rsa(1024).unwrap();
674        let public_key = secret1.public();
675
676        let device = DeviceBuilder::new(desc_content, body_content)
677            .public_key(public_key.clone())
678            //.area(area.clone().unwrap())
679            .owner(owner.clone())
680            .build();
681
682        let device_id = device.desc().device_id().object_id().to_owned();
683
684        let buf = device.to_vec().unwrap();
685        let (obj, _buf) = AnyNamedObject::raw_decode(&buf).unwrap();
686        println!("{:?}", obj.owner().unwrap());
687        assert_eq!(obj.owner().to_owned().unwrap(), owner);
688        assert_eq!(obj.calculate_id(), device_id);
689        let pk = obj.public_key().unwrap();
690        if let PublicKeyRef::Single(key) = pk {
691            assert_eq!(*key, public_key);
692        } else {
693            unreachable!();
694        }
695
696        let buf2 = obj.to_vec().unwrap();
697        assert_eq!(buf.len(), buf2.len());
698        assert_eq!(buf, buf2);
699    }
700}
701
702macro_rules! any_for_standard_target {
703    ($as_name:ident, $into_name:ident, $target:ident) => {
704        impl AnyNamedObject {
705            pub fn $as_name(&self) -> &$target {
706                match self {
707                    AnyNamedObject::Standard(s) => match s {
708                        StandardObject::$target(f) => f,
709                        _ => unreachable!(),
710                    },
711                    _ => unreachable!(),
712                }
713            }
714            pub fn $into_name(self) -> $target {
715                match self {
716                    AnyNamedObject::Standard(s) => match s {
717                        StandardObject::$target(f) => f,
718                        _ => unreachable!(),
719                    },
720                    _ => unreachable!(),
721                }
722            }
723        }
724    };
725}
726
727any_for_standard_target!(as_file, into_file, File);
728any_for_standard_target!(as_dir, into_dir, Dir);
729any_for_standard_target!(as_people, into_people, People);
730any_for_standard_target!(as_device, into_device, Device);
731any_for_standard_target!(as_group, into_group, Group);
732any_for_standard_target!(as_object_map, into_object_map, ObjectMap);