aldrin_core/introspection/
layout.rs

1use super::{ir, BuiltInType, Enum, LexicalId, Newtype, Service, Struct};
2use crate::tags::{PrimaryTag, Tag};
3use crate::{
4    Deserialize, DeserializeError, Deserializer, Serialize, SerializeError, Serializer, TypeId,
5};
6use num_enum::{IntoPrimitive, TryFromPrimitive};
7use std::collections::BTreeMap;
8
9#[derive(Debug, Clone, PartialEq, Eq)]
10#[cfg_attr(
11    feature = "serde",
12    derive(serde::Serialize, serde::Deserialize),
13    serde(rename_all = "kebab-case")
14)]
15pub enum Layout {
16    BuiltIn(BuiltInType),
17    Struct(Struct),
18    Enum(Enum),
19    Service(Service),
20    Newtype(Newtype),
21}
22
23impl Layout {
24    pub fn from_ir(layout: ir::LayoutIr, references: &BTreeMap<LexicalId, TypeId>) -> Self {
25        match layout {
26            ir::LayoutIr::BuiltIn(ty) => Self::BuiltIn(BuiltInType::from_ir(ty, references)),
27            ir::LayoutIr::Struct(ty) => Self::Struct(Struct::from_ir(ty, references)),
28            ir::LayoutIr::Enum(ty) => Self::Enum(Enum::from_ir(ty, references)),
29            ir::LayoutIr::Service(ty) => Self::Service(Service::from_ir(ty, references)),
30            ir::LayoutIr::Newtype(ty) => Self::Newtype(Newtype::from_ir(ty, references)),
31        }
32    }
33
34    pub fn as_built_in(&self) -> Option<BuiltInType> {
35        match self {
36            Self::BuiltIn(ty) => Some(*ty),
37            _ => None,
38        }
39    }
40
41    pub fn as_struct(&self) -> Option<&Struct> {
42        match self {
43            Self::Struct(ty) => Some(ty),
44            _ => None,
45        }
46    }
47
48    pub fn as_enum(&self) -> Option<&Enum> {
49        match self {
50            Self::Enum(ty) => Some(ty),
51            _ => None,
52        }
53    }
54
55    pub fn as_service(&self) -> Option<&Service> {
56        match self {
57            Self::Service(ty) => Some(ty),
58            _ => None,
59        }
60    }
61
62    pub fn as_newtype(&self) -> Option<&Newtype> {
63        match self {
64            Self::Newtype(ty) => Some(ty),
65            _ => None,
66        }
67    }
68}
69
70impl From<BuiltInType> for Layout {
71    fn from(ty: BuiltInType) -> Self {
72        Self::BuiltIn(ty)
73    }
74}
75
76impl From<Struct> for Layout {
77    fn from(ty: Struct) -> Self {
78        Self::Struct(ty)
79    }
80}
81
82impl From<Enum> for Layout {
83    fn from(ty: Enum) -> Self {
84        Self::Enum(ty)
85    }
86}
87
88impl From<Service> for Layout {
89    fn from(ty: Service) -> Self {
90        Self::Service(ty)
91    }
92}
93
94impl From<Newtype> for Layout {
95    fn from(ty: Newtype) -> Self {
96        Self::Newtype(ty)
97    }
98}
99
100#[derive(IntoPrimitive, TryFromPrimitive)]
101#[repr(u32)]
102enum LayoutVariant {
103    BuiltIn = 0,
104    Struct = 1,
105    Enum = 2,
106    Service = 3,
107    Newtype = 4,
108}
109
110impl Tag for Layout {}
111
112impl PrimaryTag for Layout {
113    type Tag = Self;
114}
115
116impl Serialize<Self> for Layout {
117    fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
118        serializer.serialize(&self)
119    }
120}
121
122impl Serialize<Layout> for &Layout {
123    fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
124        match self {
125            Layout::BuiltIn(ty) => {
126                serializer.serialize_enum::<BuiltInType>(LayoutVariant::BuiltIn, ty)
127            }
128
129            Layout::Struct(ty) => serializer.serialize_enum::<Struct>(LayoutVariant::Struct, ty),
130            Layout::Enum(ty) => serializer.serialize_enum::<Enum>(LayoutVariant::Enum, ty),
131            Layout::Service(ty) => serializer.serialize_enum::<Service>(LayoutVariant::Service, ty),
132            Layout::Newtype(ty) => serializer.serialize_enum::<Newtype>(LayoutVariant::Newtype, ty),
133        }
134    }
135}
136
137impl Deserialize<Self> for Layout {
138    fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
139        let deserializer = deserializer.deserialize_enum()?;
140
141        match deserializer.try_id()? {
142            LayoutVariant::BuiltIn => deserializer
143                .deserialize::<BuiltInType, _>()
144                .map(Self::BuiltIn),
145
146            LayoutVariant::Struct => deserializer.deserialize::<Struct, _>().map(Self::Struct),
147            LayoutVariant::Enum => deserializer.deserialize::<Enum, _>().map(Self::Enum),
148            LayoutVariant::Service => deserializer.deserialize::<Service, _>().map(Self::Service),
149            LayoutVariant::Newtype => deserializer.deserialize::<Newtype, _>().map(Self::Newtype),
150        }
151    }
152}