mirror_mirror/type_info/
mod.rs

1use core::any::type_name;
2use core::iter::Peekable;
3
4use alloc::borrow::Cow;
5use alloc::boxed::Box;
6use alloc::collections::BTreeMap;
7use alloc::string::String;
8use alloc::vec::Vec;
9
10use graph::*;
11
12use crate::enum_::EnumValue;
13use crate::key_path::value_to_usize;
14use crate::key_path::GetTypePath;
15use crate::key_path::Key;
16use crate::key_path::KeyPath;
17use crate::key_path::NamedOrNumbered;
18use crate::struct_::StructValue;
19use crate::tuple::TupleValue;
20use crate::tuple_struct::TupleStructValue;
21use crate::FromReflect;
22use crate::Reflect;
23use crate::Value;
24
25pub mod graph;
26pub mod pretty_print;
27
28#[cfg(feature = "std")]
29mod simple_type_name;
30
31pub use self::pretty_print::{PrettyPrintRoot, RootPrettyPrinter};
32#[cfg(feature = "std")]
33pub use self::simple_type_name::SimpleTypeName;
34
35/// Trait for accessing type information.
36///
37/// Will be implemented by `#[derive(Reflect)]`.
38pub trait DescribeType: 'static {
39    /// Creates a type descriptor for the current type.
40    ///
41    /// On targets with the standard library, it's done only once per process, then subsequent
42    /// accesses are "free" because the result is cached. On non-std targets, the type descriptor
43    /// is recomputed and reallocated on each call.
44    fn type_descriptor() -> Cow<'static, TypeDescriptor> {
45        #[cfg(feature = "std")]
46        {
47            use crate::__private::*;
48            use std::collections::HashMap;
49            use std::sync::RwLock;
50
51            // a map required for generic types to have different type descriptors such as
52            // `Vec<i32>` and `Vec<bool>`
53            static INFO: OnceBox<
54                RwLock<HashMap<TypeId, &'static TypeDescriptor, ahash::RandomState>>,
55            > = OnceBox::new();
56
57            let type_id = TypeId::of::<Self>();
58
59            let lock = INFO.get_or_init(|| {
60                Box::from(RwLock::new(HashMap::with_hasher(
61                    STATIC_RANDOM_STATE.clone(),
62                ))) // use seeded random state
63            });
64            if let Some(info) = lock.read().unwrap().get(&type_id) {
65                return Cow::Borrowed(info);
66            }
67
68            let mut map = lock.write().unwrap();
69            let info = map.entry(type_id).or_insert_with(|| {
70                let mut graph = TypeGraph::default();
71                let id = Self::build(&mut graph);
72                let info = TypeDescriptor::new(id, graph);
73                Box::leak(Box::new(info))
74            });
75            Cow::Borrowed(*info)
76        }
77
78        #[cfg(not(feature = "std"))]
79        {
80            use crate::__private::*;
81
82            let mut graph = TypeGraph::default();
83            let id = Self::build(&mut graph);
84            Cow::Owned(TypeDescriptor::new(id, graph))
85        }
86    }
87
88    /// Creates the full subtree describing this node in the `TypeGraph`, and returns the `NodeId`
89    /// for the root item.
90    fn build(graph: &mut TypeGraph) -> NodeId;
91}
92
93/// The root of a type.
94///
95/// Accessed via the [`DescribeType`] trait.
96///
97/// `mirror-mirror` represents types as (possibly cyclic) graphs since types can contain
98/// themselves. For example `struct Foo(Vec<Foo>)`.
99#[derive(Debug, Clone, PartialEq, Eq, Hash)]
100#[cfg_attr(feature = "speedy", derive(speedy::Readable, speedy::Writable))]
101#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
102pub struct TypeDescriptor {
103    root: NodeId,
104    graph: TypeGraph,
105}
106
107impl TypeDescriptor {
108    fn new(root: NodeId, graph: TypeGraph) -> Self {
109        Self { root, graph }
110    }
111
112    pub fn get_type(&self) -> Type<'_> {
113        Type::new(self.root, &self.graph)
114    }
115
116    pub fn type_name(&self) -> &str {
117        self.get_type().type_name()
118    }
119
120    pub fn default_value(&self) -> Option<Value> {
121        self.get_type().default_value()
122    }
123
124    pub fn has_default_value(&self) -> bool {
125        self.get_type().has_default_value()
126    }
127
128    pub fn as_struct(&self) -> Option<StructType<'_>> {
129        self.get_type().as_struct()
130    }
131
132    pub fn as_tuple_struct(&self) -> Option<TupleStructType<'_>> {
133        self.get_type().as_tuple_struct()
134    }
135
136    pub fn as_tuple(&self) -> Option<TupleType<'_>> {
137        self.get_type().as_tuple()
138    }
139
140    pub fn as_enum(&self) -> Option<EnumType<'_>> {
141        self.get_type().as_enum()
142    }
143
144    pub fn as_array(&self) -> Option<ArrayType<'_>> {
145        self.get_type().as_array()
146    }
147
148    pub fn as_list(&self) -> Option<ListType<'_>> {
149        self.get_type().as_list()
150    }
151
152    pub fn as_map(&self) -> Option<MapType<'_>> {
153        self.get_type().as_map()
154    }
155
156    pub fn as_scalar(&self) -> Option<ScalarType> {
157        self.get_type().as_scalar()
158    }
159
160    pub fn as_opaque(&self) -> Option<OpaqueType<'_>> {
161        self.get_type().as_opaque()
162    }
163}
164
165impl<'a> GetTypePath<'a> for &'a TypeDescriptor {
166    fn type_at(self, key_path: &KeyPath) -> Option<TypeAtPath<'a>> {
167        self.get_type().type_at(key_path)
168    }
169}
170
171impl<'a> GetMeta<'a> for &'a TypeDescriptor {
172    fn meta(self, key: &str) -> Option<&'a dyn Reflect> {
173        self.get_type().meta(key)
174    }
175
176    fn docs(self) -> &'a [String] {
177        self.get_type().docs()
178    }
179}
180
181#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
182pub enum Type<'a> {
183    Struct(StructType<'a>),
184    TupleStruct(TupleStructType<'a>),
185    Tuple(TupleType<'a>),
186    Enum(EnumType<'a>),
187    List(ListType<'a>),
188    Array(ArrayType<'a>),
189    Map(MapType<'a>),
190    Scalar(ScalarType),
191    Opaque(OpaqueType<'a>),
192}
193
194impl<'a> Type<'a> {
195    fn new(id: NodeId, graph: &'a TypeGraph) -> Self {
196        match graph.get(id) {
197            TypeNode::Struct(node) => {
198                let node = StructType {
199                    node: WithId::new(id, node),
200                    graph,
201                };
202                Type::Struct(node)
203            }
204            TypeNode::TupleStruct(node) => {
205                let node = TupleStructType {
206                    node: WithId::new(id, node),
207                    graph,
208                };
209                Type::TupleStruct(node)
210            }
211            TypeNode::Tuple(node) => {
212                let node = TupleType {
213                    node: WithId::new(id, node),
214                    graph,
215                };
216                Type::Tuple(node)
217            }
218            TypeNode::Enum(node) => {
219                let node = EnumType {
220                    node: WithId::new(id, node),
221                    graph,
222                };
223                Type::Enum(node)
224            }
225            TypeNode::List(node) => {
226                let node = ListType {
227                    node: WithId::new(id, node),
228                    graph,
229                };
230                Type::List(node)
231            }
232            TypeNode::Array(node) => {
233                let node = ArrayType {
234                    node: WithId::new(id, node),
235                    graph,
236                };
237                Type::Array(node)
238            }
239            TypeNode::Map(node) => {
240                let node = MapType {
241                    node: WithId::new(id, node),
242                    graph,
243                };
244                Type::Map(node)
245            }
246            TypeNode::Scalar(scalar) => {
247                let node = match scalar {
248                    ScalarNode::usize => ScalarType::usize,
249                    ScalarNode::u8 => ScalarType::u8,
250                    ScalarNode::u16 => ScalarType::u16,
251                    ScalarNode::u32 => ScalarType::u32,
252                    ScalarNode::u64 => ScalarType::u64,
253                    ScalarNode::u128 => ScalarType::u128,
254                    ScalarNode::i8 => ScalarType::i8,
255                    ScalarNode::i16 => ScalarType::i16,
256                    ScalarNode::i32 => ScalarType::i32,
257                    ScalarNode::i64 => ScalarType::i64,
258                    ScalarNode::i128 => ScalarType::i128,
259                    ScalarNode::bool => ScalarType::bool,
260                    ScalarNode::char => ScalarType::char,
261                    ScalarNode::f32 => ScalarType::f32,
262                    ScalarNode::f64 => ScalarType::f64,
263                    ScalarNode::String => ScalarType::String,
264                };
265                Type::Scalar(node)
266            }
267            TypeNode::Opaque(node) => {
268                let node = OpaqueType {
269                    node: WithId::new(id, node),
270                    graph,
271                };
272                Type::Opaque(node)
273            }
274        }
275    }
276
277    pub fn type_name(self) -> &'a str {
278        match self {
279            Type::Struct(inner) => inner.type_name(),
280            Type::TupleStruct(inner) => inner.type_name(),
281            Type::Tuple(inner) => inner.type_name(),
282            Type::Enum(inner) => inner.type_name(),
283            Type::List(inner) => inner.type_name(),
284            Type::Array(inner) => inner.type_name(),
285            Type::Map(inner) => inner.type_name(),
286            Type::Scalar(inner) => inner.type_name(),
287            Type::Opaque(inner) => inner.type_name(),
288        }
289    }
290
291    fn into_type_info_at_path(self) -> TypeAtPath<'a> {
292        match self {
293            Type::Struct(inner) => inner.into_type_info_at_path(),
294            Type::TupleStruct(inner) => inner.into_type_info_at_path(),
295            Type::Tuple(inner) => inner.into_type_info_at_path(),
296            Type::Enum(inner) => inner.into_type_info_at_path(),
297            Type::List(inner) => inner.into_type_info_at_path(),
298            Type::Array(inner) => inner.into_type_info_at_path(),
299            Type::Map(inner) => inner.into_type_info_at_path(),
300            Type::Scalar(inner) => inner.into_type_info_at_path(),
301            Type::Opaque(inner) => inner.into_type_info_at_path(),
302        }
303    }
304
305    pub fn default_value(self) -> Option<Value> {
306        match self {
307            Type::Struct(inner) => inner.default_value(),
308            Type::TupleStruct(inner) => inner.default_value(),
309            Type::Tuple(inner) => inner.default_value(),
310            Type::Enum(inner) => inner.default_value(),
311            Type::List(inner) => Some(inner.default_value()),
312            Type::Array(inner) => inner.default_value(),
313            Type::Map(inner) => Some(inner.default_value()),
314            Type::Scalar(inner) => Some(inner.default_value()),
315            Type::Opaque(inner) => inner.default_value(),
316        }
317    }
318
319    pub fn has_default_value(&self) -> bool {
320        match self {
321            Type::Struct(inner) => inner.has_default_value(),
322            Type::TupleStruct(inner) => inner.has_default_value(),
323            Type::Tuple(inner) => inner.has_default_value(),
324            Type::Enum(inner) => inner.has_default_value(),
325            Type::List(inner) => inner.has_default_value(),
326            Type::Array(inner) => inner.has_default_value(),
327            Type::Map(inner) => inner.has_default_value(),
328            Type::Scalar(inner) => inner.has_default_value(),
329            Type::Opaque(inner) => inner.has_default_value(),
330        }
331    }
332
333    pub fn into_type_descriptor(self) -> Cow<'static, TypeDescriptor> {
334        match self {
335            Type::Struct(inner) => Cow::Owned(inner.into_type_descriptor()),
336            Type::TupleStruct(inner) => Cow::Owned(inner.into_type_descriptor()),
337            Type::Tuple(inner) => Cow::Owned(inner.into_type_descriptor()),
338            Type::Enum(inner) => Cow::Owned(inner.into_type_descriptor()),
339            Type::List(inner) => Cow::Owned(inner.into_type_descriptor()),
340            Type::Array(inner) => Cow::Owned(inner.into_type_descriptor()),
341            Type::Map(inner) => Cow::Owned(inner.into_type_descriptor()),
342            Type::Scalar(inner) => match inner {
343                ScalarType::usize => <usize as DescribeType>::type_descriptor(),
344                ScalarType::u8 => <u8 as DescribeType>::type_descriptor(),
345                ScalarType::u16 => <u16 as DescribeType>::type_descriptor(),
346                ScalarType::u32 => <u32 as DescribeType>::type_descriptor(),
347                ScalarType::u64 => <u64 as DescribeType>::type_descriptor(),
348                ScalarType::u128 => <u128 as DescribeType>::type_descriptor(),
349                ScalarType::i8 => <i8 as DescribeType>::type_descriptor(),
350                ScalarType::i16 => <i16 as DescribeType>::type_descriptor(),
351                ScalarType::i32 => <i32 as DescribeType>::type_descriptor(),
352                ScalarType::i64 => <i64 as DescribeType>::type_descriptor(),
353                ScalarType::i128 => <i128 as DescribeType>::type_descriptor(),
354                ScalarType::bool => <bool as DescribeType>::type_descriptor(),
355                ScalarType::char => <char as DescribeType>::type_descriptor(),
356                ScalarType::f32 => <f32 as DescribeType>::type_descriptor(),
357                ScalarType::f64 => <f64 as DescribeType>::type_descriptor(),
358                ScalarType::String => <String as DescribeType>::type_descriptor(),
359            },
360            Type::Opaque(inner) => Cow::Owned(inner.into_type_descriptor()),
361        }
362    }
363
364    pub fn as_struct(self) -> Option<StructType<'a>> {
365        match self {
366            Type::Struct(inner) => Some(inner),
367            _ => None,
368        }
369    }
370
371    pub fn as_tuple_struct(self) -> Option<TupleStructType<'a>> {
372        match self {
373            Type::TupleStruct(inner) => Some(inner),
374            _ => None,
375        }
376    }
377
378    pub fn as_tuple(self) -> Option<TupleType<'a>> {
379        match self {
380            Type::Tuple(inner) => Some(inner),
381            _ => None,
382        }
383    }
384
385    pub fn as_enum(self) -> Option<EnumType<'a>> {
386        match self {
387            Type::Enum(inner) => Some(inner),
388            _ => None,
389        }
390    }
391
392    pub fn as_array(self) -> Option<ArrayType<'a>> {
393        match self {
394            Type::Array(inner) => Some(inner),
395            _ => None,
396        }
397    }
398
399    pub fn as_list(self) -> Option<ListType<'a>> {
400        match self {
401            Type::List(inner) => Some(inner),
402            _ => None,
403        }
404    }
405
406    pub fn as_map(self) -> Option<MapType<'a>> {
407        match self {
408            Type::Map(inner) => Some(inner),
409            _ => None,
410        }
411    }
412
413    pub fn as_scalar(self) -> Option<ScalarType> {
414        match self {
415            Type::Scalar(inner) => Some(inner),
416            _ => None,
417        }
418    }
419
420    pub fn as_opaque(self) -> Option<OpaqueType<'a>> {
421        match self {
422            Type::Opaque(inner) => Some(inner),
423            _ => None,
424        }
425    }
426}
427
428impl<'a> GetTypePath<'a> for Type<'a> {
429    fn type_at(self, key_path: &KeyPath) -> Option<TypeAtPath<'a>> {
430        self.into_type_info_at_path().type_at(key_path)
431    }
432}
433
434impl<'a> GetTypePath<'a> for StructType<'a> {
435    fn type_at(self, key_path: &KeyPath) -> Option<TypeAtPath<'a>> {
436        self.into_type_info_at_path().type_at(key_path)
437    }
438}
439
440impl<'a> GetTypePath<'a> for TupleStructType<'a> {
441    fn type_at(self, key_path: &KeyPath) -> Option<TypeAtPath<'a>> {
442        self.into_type_info_at_path().type_at(key_path)
443    }
444}
445
446impl<'a> GetTypePath<'a> for TupleType<'a> {
447    fn type_at(self, key_path: &KeyPath) -> Option<TypeAtPath<'a>> {
448        self.into_type_info_at_path().type_at(key_path)
449    }
450}
451
452impl<'a> GetTypePath<'a> for EnumType<'a> {
453    fn type_at(self, key_path: &KeyPath) -> Option<TypeAtPath<'a>> {
454        self.into_type_info_at_path().type_at(key_path)
455    }
456}
457
458impl<'a> GetTypePath<'a> for ListType<'a> {
459    fn type_at(self, key_path: &KeyPath) -> Option<TypeAtPath<'a>> {
460        self.into_type_info_at_path().type_at(key_path)
461    }
462}
463
464impl<'a> GetTypePath<'a> for MapType<'a> {
465    fn type_at(self, key_path: &KeyPath) -> Option<TypeAtPath<'a>> {
466        self.into_type_info_at_path().type_at(key_path)
467    }
468}
469
470impl GetTypePath<'static> for ScalarType {
471    fn type_at(self, key_path: &KeyPath) -> Option<TypeAtPath<'static>> {
472        self.into_type_info_at_path().type_at(key_path)
473    }
474}
475
476impl<'a> GetTypePath<'a> for Variant<'a> {
477    fn type_at(self, key_path: &KeyPath) -> Option<TypeAtPath<'a>> {
478        self.into_type_info_at_path().type_at(key_path)
479    }
480}
481
482mod private {
483    use super::*;
484
485    pub trait Sealed {}
486
487    impl Sealed for TypeDescriptor {}
488    impl<'a> Sealed for &'a TypeDescriptor {}
489    impl<'a> Sealed for TupleType<'a> {}
490    impl<'a> Sealed for ListType<'a> {}
491    impl<'a> Sealed for ArrayType<'a> {}
492    impl<'a> Sealed for MapType<'a> {}
493    impl Sealed for ScalarType {}
494    impl Sealed for Type<'_> {}
495    impl Sealed for StructType<'_> {}
496    impl Sealed for TupleStructType<'_> {}
497    impl Sealed for EnumType<'_> {}
498    impl Sealed for StructVariant<'_> {}
499    impl Sealed for TupleVariant<'_> {}
500    impl Sealed for UnitVariant<'_> {}
501    impl Sealed for UnnamedField<'_> {}
502    impl Sealed for NamedField<'_> {}
503    impl Sealed for OpaqueType<'_> {}
504    impl Sealed for Variant<'_> {}
505    impl Sealed for VariantField<'_> {}
506    impl Sealed for TypeAtPath<'_> {}
507}
508
509pub trait GetMeta<'a>: private::Sealed {
510    fn meta(self, key: &str) -> Option<&'a dyn Reflect>;
511
512    fn get_meta<T>(self, key: &str) -> Option<T>
513    where
514        T: FromReflect,
515        Self: Sized,
516    {
517        T::from_reflect(self.meta(key)?)
518    }
519
520    fn docs(self) -> &'a [String];
521}
522
523impl<'a> GetMeta<'a> for Type<'a> {
524    fn meta(self, key: &str) -> Option<&'a dyn Reflect> {
525        match self {
526            Type::Struct(inner) => inner.meta(key),
527            Type::TupleStruct(inner) => inner.meta(key),
528            Type::Enum(inner) => inner.meta(key),
529            Type::Opaque(inner) => inner.meta(key),
530            Type::Tuple(_) | Type::List(_) | Type::Array(_) | Type::Map(_) | Type::Scalar(_) => {
531                None
532            }
533        }
534    }
535
536    fn docs(self) -> &'a [String] {
537        match self {
538            Type::Struct(inner) => inner.docs(),
539            Type::TupleStruct(inner) => inner.docs(),
540            Type::Enum(inner) => inner.docs(),
541            Type::Tuple(_)
542            | Type::List(_)
543            | Type::Array(_)
544            | Type::Map(_)
545            | Type::Scalar(_)
546            | Type::Opaque(_) => &[],
547        }
548    }
549}
550
551macro_rules! impl_get_meta {
552    ($($ident:ident)*) => {
553        $(
554            impl<'a> GetMeta<'a> for $ident<'a> {
555                fn meta(self, key: &str) -> Option<&'a dyn Reflect> {
556                    Some(self.node.metadata.get(key)?.as_reflect())
557                }
558
559                fn docs(self) -> &'a [String] {
560                    &self.node.docs
561                }
562            }
563        )*
564    };
565}
566
567impl_get_meta! {
568    StructType
569    TupleStructType
570    EnumType
571    StructVariant
572    TupleVariant
573    UnitVariant
574    UnnamedField
575    NamedField
576}
577
578impl<'a> GetMeta<'a> for OpaqueType<'a> {
579    fn meta(self, key: &str) -> Option<&'a dyn Reflect> {
580        Some(self.node.metadata.get(key)?.as_reflect())
581    }
582
583    fn docs(self) -> &'a [String] {
584        &[]
585    }
586}
587
588#[allow(non_camel_case_types)]
589#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
590#[cfg_attr(feature = "speedy", derive(speedy::Readable, speedy::Writable))]
591#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
592pub enum ScalarType {
593    usize,
594    u8,
595    u16,
596    u32,
597    u64,
598    u128,
599    i8,
600    i16,
601    i32,
602    i64,
603    i128,
604    bool,
605    char,
606    f32,
607    f64,
608    String,
609}
610
611impl ScalarType {
612    pub fn type_name(self) -> &'static str {
613        match self {
614            ScalarType::usize => type_name::<usize>(),
615            ScalarType::u8 => type_name::<u8>(),
616            ScalarType::u16 => type_name::<u16>(),
617            ScalarType::u32 => type_name::<u32>(),
618            ScalarType::u64 => type_name::<u64>(),
619            ScalarType::u128 => type_name::<u128>(),
620            ScalarType::i8 => type_name::<i8>(),
621            ScalarType::i16 => type_name::<i16>(),
622            ScalarType::i32 => type_name::<i32>(),
623            ScalarType::i64 => type_name::<i64>(),
624            ScalarType::i128 => type_name::<i128>(),
625            ScalarType::bool => type_name::<bool>(),
626            ScalarType::char => type_name::<char>(),
627            ScalarType::f32 => type_name::<f32>(),
628            ScalarType::f64 => type_name::<f64>(),
629            ScalarType::String => type_name::<String>(),
630        }
631    }
632
633    fn into_type_info_at_path(self) -> TypeAtPath<'static> {
634        TypeAtPath::Scalar(self)
635    }
636
637    pub fn default_value(self) -> Value {
638        match self {
639            ScalarType::usize => usize::default().to_value(),
640            ScalarType::u8 => u8::default().to_value(),
641            ScalarType::u16 => u16::default().to_value(),
642            ScalarType::u32 => u32::default().to_value(),
643            ScalarType::u64 => u64::default().to_value(),
644            ScalarType::u128 => u128::default().to_value(),
645            ScalarType::i8 => i8::default().to_value(),
646            ScalarType::i16 => i16::default().to_value(),
647            ScalarType::i32 => i32::default().to_value(),
648            ScalarType::i64 => i64::default().to_value(),
649            ScalarType::i128 => i128::default().to_value(),
650            ScalarType::bool => bool::default().to_value(),
651            ScalarType::char => char::default().to_value(),
652            ScalarType::f32 => f32::default().to_value(),
653            ScalarType::f64 => f64::default().to_value(),
654            ScalarType::String => String::default().to_value(),
655        }
656    }
657
658    pub fn has_default_value(&self) -> bool {
659        true
660    }
661}
662
663#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
664pub struct StructType<'a> {
665    node: WithId<&'a StructNode>,
666    graph: &'a TypeGraph,
667}
668
669impl<'a> StructType<'a> {
670    pub fn type_name(self) -> &'a str {
671        &self.node.type_name
672    }
673
674    pub fn field_types(self) -> impl Iterator<Item = NamedField<'a>> {
675        self.node.field_names.iter().map(move |field_name| {
676            let node = self.node.fields.get(field_name).unwrap();
677            NamedField {
678                node,
679                graph: self.graph,
680            }
681        })
682    }
683
684    pub fn fields_len(self) -> usize {
685        self.node.fields.len()
686    }
687
688    pub fn field_type(self, name: &str) -> Option<NamedField<'a>> {
689        let node = self.node.fields.get(name)?;
690        Some(NamedField {
691            node,
692            graph: self.graph,
693        })
694    }
695
696    pub fn field_type_at(self, index: usize) -> Option<NamedField<'a>> {
697        let name = self.node.field_names.get(index)?;
698        self.field_type(name)
699    }
700
701    fn into_type_info_at_path(self) -> TypeAtPath<'a> {
702        TypeAtPath::Struct(self)
703    }
704
705    pub fn into_type_descriptor(self) -> TypeDescriptor {
706        TypeDescriptor {
707            root: self.node.id,
708            graph: self.graph.clone(),
709        }
710    }
711
712    pub fn default_value(self) -> Option<Value> {
713        let mut value = StructValue::new();
714        for field in self.field_types() {
715            value.set_field(field.name(), field.get_type().default_value()?);
716        }
717        Some(value.to_value())
718    }
719
720    pub fn has_default_value(&self) -> bool {
721        self.field_types()
722            .all(|field| field.get_type().has_default_value())
723    }
724}
725
726#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
727pub struct TupleStructType<'a> {
728    node: WithId<&'a TupleStructNode>,
729    graph: &'a TypeGraph,
730}
731
732impl<'a> TupleStructType<'a> {
733    pub fn type_name(self) -> &'a str {
734        &self.node.type_name
735    }
736
737    pub fn field_types(self) -> impl Iterator<Item = UnnamedField<'a>> {
738        self.node.fields.iter().map(|node| UnnamedField {
739            node,
740            graph: self.graph,
741        })
742    }
743
744    pub fn fields_len(self) -> usize {
745        self.node.fields.len()
746    }
747
748    pub fn field_type_at(self, index: usize) -> Option<UnnamedField<'a>> {
749        let node = self.node.fields.get(index)?;
750        Some(UnnamedField {
751            node,
752            graph: self.graph,
753        })
754    }
755
756    fn into_type_info_at_path(self) -> TypeAtPath<'a> {
757        TypeAtPath::TupleStruct(self)
758    }
759
760    pub fn into_type_descriptor(self) -> TypeDescriptor {
761        TypeDescriptor {
762            root: self.node.id,
763            graph: self.graph.clone(),
764        }
765    }
766
767    pub fn default_value(self) -> Option<Value> {
768        let mut value = TupleStructValue::new();
769        for field in self.field_types() {
770            value.push_field(field.get_type().default_value()?);
771        }
772        Some(value.to_value())
773    }
774
775    pub fn has_default_value(&self) -> bool {
776        self.field_types()
777            .all(|field| field.get_type().has_default_value())
778    }
779}
780
781#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
782pub struct TupleType<'a> {
783    node: WithId<&'a TupleNode>,
784    graph: &'a TypeGraph,
785}
786
787impl<'a> TupleType<'a> {
788    pub fn type_name(self) -> &'a str {
789        &self.node.type_name
790    }
791
792    pub fn field_types(self) -> impl Iterator<Item = UnnamedField<'a>> {
793        self.node.fields.iter().map(|node| UnnamedField {
794            node,
795            graph: self.graph,
796        })
797    }
798
799    pub fn fields_len(self) -> usize {
800        self.node.fields.len()
801    }
802
803    pub fn field_type_at(self, index: usize) -> Option<UnnamedField<'a>> {
804        let node = self.node.fields.get(index)?;
805        Some(UnnamedField {
806            node,
807            graph: self.graph,
808        })
809    }
810
811    fn into_type_info_at_path(self) -> TypeAtPath<'a> {
812        TypeAtPath::Tuple(self)
813    }
814
815    pub fn into_type_descriptor(self) -> TypeDescriptor {
816        TypeDescriptor {
817            root: self.node.id,
818            graph: self.graph.clone(),
819        }
820    }
821
822    pub fn default_value(self) -> Option<Value> {
823        let mut value = TupleValue::new();
824        for field in self.field_types() {
825            value.push_field(field.get_type().default_value()?);
826        }
827        Some(value.to_value())
828    }
829
830    pub fn has_default_value(&self) -> bool {
831        self.field_types()
832            .all(|field| field.get_type().has_default_value())
833    }
834}
835
836#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
837pub struct EnumType<'a> {
838    node: WithId<&'a EnumNode>,
839    graph: &'a TypeGraph,
840}
841
842impl<'a> EnumType<'a> {
843    pub fn type_name(self) -> &'a str {
844        &self.node.type_name
845    }
846
847    pub fn variants(self) -> impl Iterator<Item = Variant<'a>> {
848        self.node.variants.iter().map(move |variant| match variant {
849            VariantNode::Struct(node) => Variant::Struct(StructVariant {
850                node,
851                enum_node: self.node,
852                graph: self.graph,
853            }),
854            VariantNode::Tuple(node) => Variant::Tuple(TupleVariant {
855                node,
856                enum_node: self.node,
857                graph: self.graph,
858            }),
859            VariantNode::Unit(node) => Variant::Unit(UnitVariant {
860                node,
861                enum_node: self.node,
862                graph: self.graph,
863            }),
864        })
865    }
866
867    pub fn variants_len(self) -> usize {
868        self.node.variants.len()
869    }
870
871    pub fn variant(self, name: &str) -> Option<Variant<'a>> {
872        self.variants().find(|variant| variant.name() == name)
873    }
874
875    fn into_type_info_at_path(self) -> TypeAtPath<'a> {
876        TypeAtPath::Enum(self)
877    }
878
879    pub fn into_type_descriptor(self) -> TypeDescriptor {
880        TypeDescriptor {
881            root: self.node.id,
882            graph: self.graph.clone(),
883        }
884    }
885
886    pub fn default_value(self) -> Option<Value> {
887        let mut variants = self.variants();
888        let first_variant = variants.next()?;
889        first_variant.default_value()
890    }
891
892    pub fn has_default_value(&self) -> bool {
893        let mut variants = self.variants();
894        variants
895            .next()
896            .map_or(false, |first_variant| first_variant.has_default_value())
897    }
898}
899
900#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
901pub enum Variant<'a> {
902    Struct(StructVariant<'a>),
903    Tuple(TupleVariant<'a>),
904    Unit(UnitVariant<'a>),
905}
906
907impl<'a> Variant<'a> {
908    pub fn name(self) -> &'a str {
909        match self {
910            Variant::Struct(inner) => inner.name(),
911            Variant::Tuple(inner) => inner.name(),
912            Variant::Unit(inner) => inner.name(),
913        }
914    }
915
916    pub fn type_name(self) -> &'a str {
917        match self {
918            Variant::Struct(inner) => inner.type_name(),
919            Variant::Tuple(inner) => inner.type_name(),
920            Variant::Unit(inner) => inner.type_name(),
921        }
922    }
923
924    pub fn field_types(self) -> impl Iterator<Item = VariantField<'a>> {
925        match self {
926            Variant::Struct(inner) => Box::new(inner.field_types().map(VariantField::Named))
927                as Box<dyn Iterator<Item = VariantField<'a>>>,
928            Variant::Tuple(inner) => Box::new(inner.field_types().map(VariantField::Unnamed)),
929            Variant::Unit(_) => Box::new(core::iter::empty()),
930        }
931    }
932
933    pub fn fields_len(self) -> usize {
934        match self {
935            Variant::Struct(inner) => inner.fields_len(),
936            Variant::Tuple(inner) => inner.fields_len(),
937            Variant::Unit(_) => 0,
938        }
939    }
940
941    pub fn field_type(self, name: &str) -> Option<NamedField<'a>> {
942        match self {
943            Variant::Struct(inner) => inner.field_type(name),
944            Variant::Tuple(_) | Variant::Unit(_) => None,
945        }
946    }
947
948    pub fn field_type_at(self, index: usize) -> Option<VariantField<'a>> {
949        match self {
950            Variant::Struct(inner) => inner.field_type_at(index).map(VariantField::Named),
951            Variant::Tuple(inner) => inner.field_type_at(index).map(VariantField::Unnamed),
952            Variant::Unit(_) => None,
953        }
954    }
955
956    pub fn enum_type(self) -> EnumType<'a> {
957        match self {
958            Variant::Struct(inner) => inner.enum_type(),
959            Variant::Tuple(inner) => inner.enum_type(),
960            Variant::Unit(inner) => inner.enum_type(),
961        }
962    }
963
964    fn into_type_info_at_path(self) -> TypeAtPath<'a> {
965        TypeAtPath::Variant(self)
966    }
967
968    pub fn default_value(self) -> Option<Value> {
969        match self {
970            Variant::Struct(variant) => variant.default_value(),
971            Variant::Tuple(variant) => variant.default_value(),
972            Variant::Unit(variant) => Some(variant.default_value()),
973        }
974    }
975
976    pub fn has_default_value(&self) -> bool {
977        match self {
978            Variant::Struct(variant) => variant.has_default_value(),
979            Variant::Tuple(variant) => variant.has_default_value(),
980            Variant::Unit(variant) => variant.has_default_value(),
981        }
982    }
983}
984
985impl<'a> GetMeta<'a> for Variant<'a> {
986    fn meta(self, key: &str) -> Option<&'a dyn Reflect> {
987        match self {
988            Variant::Struct(inner) => inner.meta(key),
989            Variant::Tuple(inner) => inner.meta(key),
990            Variant::Unit(inner) => inner.meta(key),
991        }
992    }
993
994    fn docs(self) -> &'a [String] {
995        match self {
996            Variant::Struct(inner) => inner.docs(),
997            Variant::Tuple(inner) => inner.docs(),
998            Variant::Unit(inner) => inner.docs(),
999        }
1000    }
1001}
1002
1003#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1004pub enum VariantField<'a> {
1005    Named(NamedField<'a>),
1006    Unnamed(UnnamedField<'a>),
1007}
1008
1009impl<'a> VariantField<'a> {
1010    pub fn get_type(self) -> Type<'a> {
1011        match self {
1012            VariantField::Named(inner) => inner.get_type(),
1013            VariantField::Unnamed(inner) => inner.get_type(),
1014        }
1015    }
1016
1017    pub fn name(self) -> Option<&'a str> {
1018        match self {
1019            VariantField::Named(inner) => Some(inner.name()),
1020            VariantField::Unnamed(_) => None,
1021        }
1022    }
1023}
1024
1025impl<'a> GetMeta<'a> for VariantField<'a> {
1026    fn meta(self, key: &str) -> Option<&'a dyn Reflect> {
1027        match self {
1028            VariantField::Named(inner) => inner.meta(key),
1029            VariantField::Unnamed(inner) => inner.meta(key),
1030        }
1031    }
1032
1033    fn docs(self) -> &'a [String] {
1034        match self {
1035            VariantField::Named(inner) => inner.docs(),
1036            VariantField::Unnamed(inner) => inner.docs(),
1037        }
1038    }
1039}
1040
1041#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1042pub struct StructVariant<'a> {
1043    node: &'a StructVariantNode,
1044    enum_node: WithId<&'a EnumNode>,
1045    graph: &'a TypeGraph,
1046}
1047
1048impl<'a> StructVariant<'a> {
1049    pub fn name(self) -> &'a str {
1050        &self.node.name
1051    }
1052
1053    pub fn type_name(self) -> &'a str {
1054        self.enum_type().type_name()
1055    }
1056
1057    pub fn field_types(self) -> impl Iterator<Item = NamedField<'a>> {
1058        self.node.field_names.iter().map(|field_name| {
1059            let node = self.node.fields.get(field_name).unwrap();
1060            NamedField {
1061                node,
1062                graph: self.graph,
1063            }
1064        })
1065    }
1066
1067    pub fn fields_len(self) -> usize {
1068        self.node.fields.len()
1069    }
1070
1071    pub fn field_type(self, name: &str) -> Option<NamedField<'a>> {
1072        let node = self.node.fields.get(name)?;
1073        Some(NamedField {
1074            node,
1075            graph: self.graph,
1076        })
1077    }
1078
1079    pub fn field_type_at(self, index: usize) -> Option<NamedField<'a>> {
1080        let name = self.node.field_names.get(index)?;
1081        self.field_type(name)
1082    }
1083
1084    pub fn enum_type(self) -> EnumType<'a> {
1085        EnumType {
1086            node: self.enum_node,
1087            graph: self.graph,
1088        }
1089    }
1090
1091    pub fn default_value(self) -> Option<Value> {
1092        let mut value = EnumValue::new_struct_variant(self.name());
1093        for field in self.field_types() {
1094            value.set_struct_field(field.name(), field.get_type().default_value()?);
1095        }
1096        Some(value.finish().to_value())
1097    }
1098
1099    pub fn has_default_value(&self) -> bool {
1100        self.field_types()
1101            .all(|field| field.get_type().has_default_value())
1102    }
1103}
1104
1105#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1106pub struct TupleVariant<'a> {
1107    node: &'a TupleVariantNode,
1108    enum_node: WithId<&'a EnumNode>,
1109    graph: &'a TypeGraph,
1110}
1111
1112impl<'a> TupleVariant<'a> {
1113    pub fn name(self) -> &'a str {
1114        &self.node.name
1115    }
1116
1117    pub fn type_name(self) -> &'a str {
1118        self.enum_type().type_name()
1119    }
1120
1121    pub fn field_types(self) -> impl Iterator<Item = UnnamedField<'a>> {
1122        self.node.fields.iter().map(|node| UnnamedField {
1123            node,
1124            graph: self.graph,
1125        })
1126    }
1127
1128    pub fn fields_len(self) -> usize {
1129        self.node.fields.len()
1130    }
1131
1132    pub fn field_type_at(self, index: usize) -> Option<UnnamedField<'a>> {
1133        let node = self.node.fields.get(index)?;
1134        Some(UnnamedField {
1135            node,
1136            graph: self.graph,
1137        })
1138    }
1139
1140    pub fn enum_type(self) -> EnumType<'a> {
1141        EnumType {
1142            node: self.enum_node,
1143            graph: self.graph,
1144        }
1145    }
1146
1147    pub fn default_value(self) -> Option<Value> {
1148        let mut value = EnumValue::new_tuple_variant(self.name());
1149        for field in self.field_types() {
1150            value.push_tuple_field(field.get_type().default_value()?);
1151        }
1152        Some(value.finish().to_value())
1153    }
1154
1155    pub fn has_default_value(&self) -> bool {
1156        self.field_types()
1157            .all(|field| field.get_type().has_default_value())
1158    }
1159}
1160
1161#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1162pub struct UnitVariant<'a> {
1163    node: &'a UnitVariantNode,
1164    enum_node: WithId<&'a EnumNode>,
1165    graph: &'a TypeGraph,
1166}
1167
1168impl<'a> UnitVariant<'a> {
1169    pub fn name(self) -> &'a str {
1170        &self.node.name
1171    }
1172
1173    pub fn type_name(self) -> &'a str {
1174        self.enum_type().type_name()
1175    }
1176
1177    pub fn enum_type(self) -> EnumType<'a> {
1178        EnumType {
1179            node: self.enum_node,
1180            graph: self.graph,
1181        }
1182    }
1183
1184    pub fn default_value(self) -> Value {
1185        EnumValue::new_unit_variant(self.name()).to_value()
1186    }
1187
1188    pub fn has_default_value(&self) -> bool {
1189        true
1190    }
1191}
1192
1193#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1194pub struct UnnamedField<'a> {
1195    node: &'a UnnamedFieldNode,
1196    graph: &'a TypeGraph,
1197}
1198
1199impl<'a> UnnamedField<'a> {
1200    pub fn get_type(self) -> Type<'a> {
1201        Type::new(self.node.id, self.graph)
1202    }
1203
1204    fn into_type_info_at_path(self) -> TypeAtPath<'a> {
1205        self.get_type().into_type_info_at_path()
1206    }
1207}
1208
1209#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1210pub struct NamedField<'a> {
1211    node: &'a NamedFieldNode,
1212    graph: &'a TypeGraph,
1213}
1214
1215impl<'a> NamedField<'a> {
1216    pub fn name(self) -> &'a str {
1217        &self.node.name
1218    }
1219
1220    pub fn get_type(self) -> Type<'a> {
1221        Type::new(self.node.id, self.graph)
1222    }
1223
1224    fn into_type_info_at_path(self) -> TypeAtPath<'a> {
1225        self.get_type().into_type_info_at_path()
1226    }
1227}
1228
1229#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1230pub struct ArrayType<'a> {
1231    node: WithId<&'a ArrayNode>,
1232    graph: &'a TypeGraph,
1233}
1234
1235impl<'a> ArrayType<'a> {
1236    pub fn type_name(self) -> &'a str {
1237        &self.node.type_name
1238    }
1239
1240    pub fn element_type(self) -> Type<'a> {
1241        Type::new(self.node.field_type_id, self.graph)
1242    }
1243
1244    pub fn len(self) -> usize {
1245        self.node.len
1246    }
1247
1248    pub fn is_empty(self) -> bool {
1249        self.node.len == 0
1250    }
1251
1252    fn into_type_info_at_path(self) -> TypeAtPath<'a> {
1253        TypeAtPath::Array(self)
1254    }
1255
1256    pub fn into_type_descriptor(self) -> TypeDescriptor {
1257        TypeDescriptor {
1258            root: self.node.id,
1259            graph: self.graph.clone(),
1260        }
1261    }
1262
1263    pub fn default_value(self) -> Option<Value> {
1264        let mut acc = Vec::with_capacity(self.len());
1265        for _ in 0..self.len() {
1266            acc.push(self.element_type().default_value()?);
1267        }
1268        Some(acc.to_value())
1269    }
1270
1271    pub fn has_default_value(&self) -> bool {
1272        self.element_type().has_default_value()
1273    }
1274}
1275
1276#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1277pub struct ListType<'a> {
1278    node: WithId<&'a ListNode>,
1279    graph: &'a TypeGraph,
1280}
1281
1282impl<'a> ListType<'a> {
1283    pub fn type_name(self) -> &'a str {
1284        &self.node.type_name
1285    }
1286
1287    pub fn element_type(self) -> Type<'a> {
1288        Type::new(self.node.field_type_id, self.graph)
1289    }
1290
1291    fn into_type_info_at_path(self) -> TypeAtPath<'a> {
1292        TypeAtPath::List(self)
1293    }
1294
1295    pub fn into_type_descriptor(self) -> TypeDescriptor {
1296        TypeDescriptor {
1297            root: self.node.id,
1298            graph: self.graph.clone(),
1299        }
1300    }
1301
1302    pub fn default_value(self) -> Value {
1303        Vec::<()>::new().to_value()
1304    }
1305
1306    pub fn has_default_value(&self) -> bool {
1307        true
1308    }
1309}
1310
1311#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1312pub struct MapType<'a> {
1313    node: WithId<&'a MapNode>,
1314    graph: &'a TypeGraph,
1315}
1316
1317impl<'a> MapType<'a> {
1318    pub fn type_name(self) -> &'a str {
1319        &self.node.type_name
1320    }
1321
1322    pub fn key_type(self) -> Type<'a> {
1323        Type::new(self.node.key_type_id, self.graph)
1324    }
1325
1326    pub fn value_type(self) -> Type<'a> {
1327        Type::new(self.node.value_type_id, self.graph)
1328    }
1329
1330    fn into_type_info_at_path(self) -> TypeAtPath<'a> {
1331        TypeAtPath::Map(self)
1332    }
1333
1334    pub fn into_type_descriptor(self) -> TypeDescriptor {
1335        TypeDescriptor {
1336            root: self.node.id,
1337            graph: self.graph.clone(),
1338        }
1339    }
1340
1341    pub fn default_value(self) -> Value {
1342        BTreeMap::<(), ()>::new().to_value()
1343    }
1344
1345    pub fn has_default_value(&self) -> bool {
1346        true
1347    }
1348}
1349
1350#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1351pub struct OpaqueType<'a> {
1352    node: WithId<&'a OpaqueNode>,
1353    graph: &'a TypeGraph,
1354}
1355
1356impl<'a> OpaqueType<'a> {
1357    pub fn type_name(self) -> &'a str {
1358        &self.node.type_name
1359    }
1360
1361    fn into_type_info_at_path(self) -> TypeAtPath<'a> {
1362        TypeAtPath::Opaque(self)
1363    }
1364
1365    pub fn into_type_descriptor(self) -> TypeDescriptor {
1366        TypeDescriptor {
1367            root: self.node.id,
1368            graph: self.graph.clone(),
1369        }
1370    }
1371
1372    pub fn default_value(self) -> Option<Value> {
1373        self.node.default_value.clone()
1374    }
1375
1376    pub fn has_default_value(&self) -> bool {
1377        self.node.default_value.is_some()
1378    }
1379}
1380
1381/// A superset of `Type` that can also describe `Variant`s.
1382#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1383pub enum TypeAtPath<'a> {
1384    Struct(StructType<'a>),
1385    TupleStruct(TupleStructType<'a>),
1386    Tuple(TupleType<'a>),
1387    Enum(EnumType<'a>),
1388    Variant(Variant<'a>),
1389    List(ListType<'a>),
1390    Array(ArrayType<'a>),
1391    Map(MapType<'a>),
1392    Scalar(ScalarType),
1393    Opaque(OpaqueType<'a>),
1394}
1395
1396impl<'a> GetMeta<'a> for TypeAtPath<'a> {
1397    fn meta(self, key: &str) -> Option<&'a dyn Reflect> {
1398        match self {
1399            TypeAtPath::Struct(inner) => inner.meta(key),
1400            TypeAtPath::TupleStruct(inner) => inner.meta(key),
1401            TypeAtPath::Enum(inner) => inner.meta(key),
1402            TypeAtPath::Opaque(inner) => inner.meta(key),
1403            TypeAtPath::Variant(_)
1404            | TypeAtPath::Tuple(_)
1405            | TypeAtPath::List(_)
1406            | TypeAtPath::Array(_)
1407            | TypeAtPath::Map(_)
1408            | TypeAtPath::Scalar(_) => None,
1409        }
1410    }
1411
1412    fn docs(self) -> &'a [String] {
1413        match self {
1414            TypeAtPath::Struct(inner) => inner.docs(),
1415            TypeAtPath::TupleStruct(inner) => inner.docs(),
1416            TypeAtPath::Enum(inner) => inner.docs(),
1417            TypeAtPath::Variant(_)
1418            | TypeAtPath::Tuple(_)
1419            | TypeAtPath::List(_)
1420            | TypeAtPath::Array(_)
1421            | TypeAtPath::Map(_)
1422            | TypeAtPath::Scalar(_)
1423            | TypeAtPath::Opaque(_) => &[],
1424        }
1425    }
1426}
1427
1428impl<'a> TypeAtPath<'a> {
1429    pub fn default_value(self) -> Option<Value> {
1430        match self {
1431            TypeAtPath::Struct(inner) => inner.default_value(),
1432            TypeAtPath::TupleStruct(inner) => inner.default_value(),
1433            TypeAtPath::Tuple(inner) => inner.default_value(),
1434            TypeAtPath::Enum(inner) => inner.default_value(),
1435            TypeAtPath::Variant(inner) => inner.default_value(),
1436            TypeAtPath::List(inner) => Some(inner.default_value()),
1437            TypeAtPath::Array(inner) => inner.default_value(),
1438            TypeAtPath::Map(inner) => Some(inner.default_value()),
1439            TypeAtPath::Scalar(inner) => Some(inner.default_value()),
1440            TypeAtPath::Opaque(inner) => inner.default_value(),
1441        }
1442    }
1443
1444    pub fn has_default_value(&self) -> bool {
1445        match self {
1446            TypeAtPath::Struct(inner) => inner.has_default_value(),
1447            TypeAtPath::TupleStruct(inner) => inner.has_default_value(),
1448            TypeAtPath::Tuple(inner) => inner.has_default_value(),
1449            TypeAtPath::Enum(inner) => inner.has_default_value(),
1450            TypeAtPath::Variant(inner) => inner.has_default_value(),
1451            TypeAtPath::List(inner) => inner.has_default_value(),
1452            TypeAtPath::Array(inner) => inner.has_default_value(),
1453            TypeAtPath::Map(inner) => inner.has_default_value(),
1454            TypeAtPath::Scalar(inner) => inner.has_default_value(),
1455            TypeAtPath::Opaque(inner) => inner.has_default_value(),
1456        }
1457    }
1458
1459    pub fn type_name(self) -> &'a str {
1460        match self {
1461            TypeAtPath::Struct(inner) => inner.type_name(),
1462            TypeAtPath::TupleStruct(inner) => inner.type_name(),
1463            TypeAtPath::Tuple(inner) => inner.type_name(),
1464            TypeAtPath::Enum(inner) => inner.type_name(),
1465            TypeAtPath::Variant(inner) => inner.type_name(),
1466            TypeAtPath::List(inner) => inner.type_name(),
1467            TypeAtPath::Array(inner) => inner.type_name(),
1468            TypeAtPath::Map(inner) => inner.type_name(),
1469            TypeAtPath::Scalar(inner) => inner.type_name(),
1470            TypeAtPath::Opaque(inner) => inner.type_name(),
1471        }
1472    }
1473
1474    pub fn as_struct(self) -> Option<StructType<'a>> {
1475        match self {
1476            Self::Struct(inner) => Some(inner),
1477            _ => None,
1478        }
1479    }
1480
1481    pub fn as_tuple_struct(self) -> Option<TupleStructType<'a>> {
1482        match self {
1483            Self::TupleStruct(inner) => Some(inner),
1484            _ => None,
1485        }
1486    }
1487
1488    pub fn as_tuple(self) -> Option<TupleType<'a>> {
1489        match self {
1490            Self::Tuple(inner) => Some(inner),
1491            _ => None,
1492        }
1493    }
1494
1495    pub fn as_enum(self) -> Option<EnumType<'a>> {
1496        match self {
1497            Self::Enum(inner) => Some(inner),
1498            _ => None,
1499        }
1500    }
1501
1502    pub fn as_variant(self) -> Option<Variant<'a>> {
1503        match self {
1504            Self::Variant(inner) => Some(inner),
1505            _ => None,
1506        }
1507    }
1508
1509    pub fn as_array(self) -> Option<ArrayType<'a>> {
1510        match self {
1511            Self::Array(inner) => Some(inner),
1512            _ => None,
1513        }
1514    }
1515
1516    pub fn as_list(self) -> Option<ListType<'a>> {
1517        match self {
1518            Self::List(inner) => Some(inner),
1519            _ => None,
1520        }
1521    }
1522
1523    pub fn as_map(self) -> Option<MapType<'a>> {
1524        match self {
1525            Self::Map(inner) => Some(inner),
1526            _ => None,
1527        }
1528    }
1529
1530    pub fn as_scalar(self) -> Option<ScalarType> {
1531        match self {
1532            Self::Scalar(inner) => Some(inner),
1533            _ => None,
1534        }
1535    }
1536
1537    pub fn as_opaque(self) -> Option<OpaqueType<'a>> {
1538        match self {
1539            Self::Opaque(inner) => Some(inner),
1540            _ => None,
1541        }
1542    }
1543}
1544
1545impl<'a> GetTypePath<'a> for TypeAtPath<'a> {
1546    fn type_at(self, key_path: &KeyPath) -> Option<TypeAtPath<'a>> {
1547        fn go<'a, 'b>(
1548            type_info: TypeAtPath<'a>,
1549            mut stack: Peekable<impl Iterator<Item = &'b Key>>,
1550        ) -> Option<TypeAtPath<'a>> {
1551            let head = stack.next()?;
1552
1553            let value_at_key: TypeAtPath<'_> = match head {
1554                // .foo
1555                Key::Field(NamedOrNumbered::Named(key)) => match type_info {
1556                    TypeAtPath::Struct(struct_) => {
1557                        struct_.field_type(key)?.into_type_info_at_path()
1558                    }
1559                    TypeAtPath::Variant(variant) => match variant {
1560                        Variant::Struct(struct_variant) => {
1561                            struct_variant.field_type(key)?.into_type_info_at_path()
1562                        }
1563                        Variant::Tuple(_) | Variant::Unit(_) => return None,
1564                    },
1565                    TypeAtPath::Enum(_)
1566                    | TypeAtPath::TupleStruct(_)
1567                    | TypeAtPath::Tuple(_)
1568                    | TypeAtPath::List(_)
1569                    | TypeAtPath::Array(_)
1570                    | TypeAtPath::Map(_)
1571                    | TypeAtPath::Scalar(_)
1572                    | TypeAtPath::Opaque(_) => return None,
1573                },
1574                // .0
1575                Key::Field(NamedOrNumbered::Numbered(index)) => match type_info {
1576                    TypeAtPath::TupleStruct(tuple_struct) => {
1577                        tuple_struct.field_type_at(*index)?.into_type_info_at_path()
1578                    }
1579                    TypeAtPath::Tuple(tuple) => {
1580                        tuple.field_type_at(*index)?.into_type_info_at_path()
1581                    }
1582                    TypeAtPath::Variant(variant) => match variant {
1583                        Variant::Tuple(tuple) => {
1584                            tuple.field_type_at(*index)?.into_type_info_at_path()
1585                        }
1586                        Variant::Struct(_) | Variant::Unit(_) => return None,
1587                    },
1588                    TypeAtPath::Struct(_)
1589                    | TypeAtPath::Enum(_)
1590                    | TypeAtPath::List(_)
1591                    | TypeAtPath::Array(_)
1592                    | TypeAtPath::Map(_)
1593                    | TypeAtPath::Scalar(_)
1594                    | TypeAtPath::Opaque(_) => return None,
1595                },
1596                // ["foo"] or [0]
1597                Key::Get(key) => match type_info {
1598                    TypeAtPath::Map(map) => map.value_type().into_type_info_at_path(),
1599                    TypeAtPath::List(list) => {
1600                        if value_to_usize(key).is_some() {
1601                            list.element_type().into_type_info_at_path()
1602                        } else {
1603                            return None;
1604                        }
1605                    }
1606                    TypeAtPath::Array(array) => {
1607                        if value_to_usize(key).is_some() {
1608                            array.element_type().into_type_info_at_path()
1609                        } else {
1610                            return None;
1611                        }
1612                    }
1613                    TypeAtPath::Struct(_)
1614                    | TypeAtPath::TupleStruct(_)
1615                    | TypeAtPath::Tuple(_)
1616                    | TypeAtPath::Enum(_)
1617                    | TypeAtPath::Variant(_)
1618                    | TypeAtPath::Scalar(_)
1619                    | TypeAtPath::Opaque(_) => return None,
1620                },
1621                // ::Some
1622                Key::Variant(variant) => match type_info {
1623                    TypeAtPath::Enum(enum_) => enum_
1624                        .variants()
1625                        .find(|v| v.name() == variant)?
1626                        .into_type_info_at_path(),
1627                    TypeAtPath::Variant(v) => {
1628                        if v.name() == variant {
1629                            v.into_type_info_at_path()
1630                        } else {
1631                            return None;
1632                        }
1633                    }
1634                    TypeAtPath::Struct(_)
1635                    | TypeAtPath::TupleStruct(_)
1636                    | TypeAtPath::Tuple(_)
1637                    | TypeAtPath::List(_)
1638                    | TypeAtPath::Array(_)
1639                    | TypeAtPath::Map(_)
1640                    | TypeAtPath::Scalar(_)
1641                    | TypeAtPath::Opaque(_) => return None,
1642                },
1643            };
1644
1645            if stack.peek().is_none() {
1646                Some(value_at_key)
1647            } else {
1648                go(value_at_key, stack)
1649            }
1650        }
1651
1652        if key_path.is_empty() {
1653            return Some(self);
1654        }
1655
1656        go(self, key_path.path.iter().peekable())
1657    }
1658}