aldrin_core/introspection/
layout.rs1use 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}