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