aldrin_core/introspection/
struct_ty.rs1use super::{ir, Field, LexicalId, StructFallback};
2use crate::tags::{self, 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 struct Struct {
16 schema: String,
17 name: String,
18
19 #[cfg_attr(
20 feature = "serde",
21 serde(default, skip_serializing_if = "Option::is_none")
22 )]
23 doc: Option<String>,
24
25 #[cfg_attr(
26 feature = "serde",
27 serde(default, skip_serializing_if = "BTreeMap::is_empty")
28 )]
29 fields: BTreeMap<u32, Field>,
30
31 #[cfg_attr(
32 feature = "serde",
33 serde(default, skip_serializing_if = "Option::is_none")
34 )]
35 fallback: Option<StructFallback>,
36}
37
38impl Struct {
39 pub fn from_ir(ty: ir::StructIr, references: &BTreeMap<LexicalId, TypeId>) -> Self {
40 Self {
41 schema: ty.schema,
42 name: ty.name,
43 doc: ty.doc,
44 fields: ty
45 .fields
46 .into_iter()
47 .map(|(id, field)| (id, Field::from_ir(field, references)))
48 .collect(),
49 fallback: ty.fallback.map(StructFallback::from_ir),
50 }
51 }
52
53 pub fn schema(&self) -> &str {
54 &self.schema
55 }
56
57 pub fn name(&self) -> &str {
58 &self.name
59 }
60
61 pub fn doc(&self) -> Option<&str> {
62 self.doc.as_deref()
63 }
64
65 pub fn fields(&self) -> &BTreeMap<u32, Field> {
66 &self.fields
67 }
68
69 pub fn fallback(&self) -> Option<&StructFallback> {
70 self.fallback.as_ref()
71 }
72}
73
74#[derive(IntoPrimitive, TryFromPrimitive)]
75#[repr(u32)]
76enum StructField {
77 Schema = 0,
78 Name = 1,
79 Doc = 2,
80 Fields = 3,
81 Fallback = 4,
82}
83
84impl Tag for Struct {}
85
86impl PrimaryTag for Struct {
87 type Tag = Self;
88}
89
90impl Serialize<Self> for Struct {
91 fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
92 serializer.serialize(&self)
93 }
94}
95
96impl Serialize<Struct> for &Struct {
97 fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
98 let mut serializer = serializer.serialize_struct2()?;
99
100 serializer.serialize::<tags::String>(StructField::Schema, &self.schema)?;
101 serializer.serialize::<tags::String>(StructField::Name, &self.name)?;
102 serializer.serialize_if_some::<tags::Option<tags::String>>(StructField::Doc, &self.doc)?;
103 serializer.serialize::<tags::Map<tags::U32, Field>>(StructField::Fields, &self.fields)?;
104
105 serializer.serialize_if_some::<tags::Option<StructFallback>>(
106 StructField::Fallback,
107 &self.fallback,
108 )?;
109
110 serializer.finish()
111 }
112}
113
114impl Deserialize<Self> for Struct {
115 fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
116 let mut deserializer = deserializer.deserialize_struct()?;
117
118 let mut schema = None;
119 let mut name = None;
120 let mut doc = None;
121 let mut fields = None;
122 let mut fallback = None;
123
124 while let Some(deserializer) = deserializer.deserialize()? {
125 match deserializer.try_id() {
126 Ok(StructField::Schema) => {
127 schema = deserializer.deserialize::<tags::String, _>().map(Some)?;
128 }
129
130 Ok(StructField::Name) => {
131 name = deserializer.deserialize::<tags::String, _>().map(Some)?;
132 }
133
134 Ok(StructField::Doc) => {
135 doc = deserializer.deserialize::<tags::Option<tags::String>, _>()?;
136 }
137
138 Ok(StructField::Fields) => {
139 fields = deserializer
140 .deserialize::<tags::Map<tags::U32, Field>, _>()
141 .map(Some)?;
142 }
143
144 Ok(StructField::Fallback) => {
145 fallback = deserializer.deserialize::<tags::Option<StructFallback>, _>()?;
146 }
147
148 Err(_) => deserializer.skip()?,
149 }
150 }
151
152 deserializer.finish(Self {
153 schema: schema.ok_or(DeserializeError::InvalidSerialization)?,
154 name: name.ok_or(DeserializeError::InvalidSerialization)?,
155 doc,
156 fields: fields.ok_or(DeserializeError::InvalidSerialization)?,
157 fallback,
158 })
159 }
160}