aldrin_core/introspection/
service.rs1use super::{ir, Event, EventFallback, Function, FunctionFallback, LexicalId};
2use crate::tags::{self, PrimaryTag, Tag};
3use crate::{
4 Deserialize, DeserializeError, Deserializer, Serialize, SerializeError, Serializer,
5 ServiceUuid, TypeId,
6};
7use num_enum::{IntoPrimitive, TryFromPrimitive};
8use std::collections::BTreeMap;
9
10#[derive(Debug, Clone, PartialEq, Eq)]
11#[cfg_attr(
12 feature = "serde",
13 derive(serde::Serialize, serde::Deserialize),
14 serde(rename_all = "kebab-case")
15)]
16pub struct Service {
17 schema: String,
18 name: String,
19
20 #[cfg_attr(
21 feature = "serde",
22 serde(default, skip_serializing_if = "Option::is_none")
23 )]
24 doc: Option<String>,
25 uuid: ServiceUuid,
26 version: u32,
27
28 #[cfg_attr(
29 feature = "serde",
30 serde(default, skip_serializing_if = "BTreeMap::is_empty")
31 )]
32 functions: BTreeMap<u32, Function>,
33
34 #[cfg_attr(
35 feature = "serde",
36 serde(default, skip_serializing_if = "BTreeMap::is_empty")
37 )]
38 events: BTreeMap<u32, Event>,
39
40 #[cfg_attr(
41 feature = "serde",
42 serde(default, skip_serializing_if = "Option::is_none")
43 )]
44 function_fallback: Option<FunctionFallback>,
45
46 #[cfg_attr(
47 feature = "serde",
48 serde(default, skip_serializing_if = "Option::is_none")
49 )]
50 event_fallback: Option<EventFallback>,
51}
52
53impl Service {
54 pub fn from_ir(ty: ir::ServiceIr, references: &BTreeMap<LexicalId, TypeId>) -> Self {
55 Self {
56 schema: ty.schema,
57 name: ty.name,
58 doc: ty.doc,
59 uuid: ty.uuid,
60 version: ty.version,
61
62 functions: ty
63 .functions
64 .into_iter()
65 .map(|(id, func)| (id, Function::from_ir(func, references)))
66 .collect(),
67
68 events: ty
69 .events
70 .into_iter()
71 .map(|(id, ev)| (id, Event::from_ir(ev, references)))
72 .collect(),
73
74 function_fallback: ty.function_fallback.map(FunctionFallback::from_ir),
75 event_fallback: ty.event_fallback.map(EventFallback::from_ir),
76 }
77 }
78
79 pub fn schema(&self) -> &str {
80 &self.schema
81 }
82
83 pub fn name(&self) -> &str {
84 &self.name
85 }
86
87 pub fn doc(&self) -> Option<&str> {
88 self.doc.as_deref()
89 }
90
91 pub fn uuid(&self) -> ServiceUuid {
92 self.uuid
93 }
94
95 pub fn version(&self) -> u32 {
96 self.version
97 }
98
99 pub fn functions(&self) -> &BTreeMap<u32, Function> {
100 &self.functions
101 }
102
103 pub fn events(&self) -> &BTreeMap<u32, Event> {
104 &self.events
105 }
106
107 pub fn function_fallback(&self) -> Option<&FunctionFallback> {
108 self.function_fallback.as_ref()
109 }
110
111 pub fn event_fallback(&self) -> Option<&EventFallback> {
112 self.event_fallback.as_ref()
113 }
114}
115
116#[derive(IntoPrimitive, TryFromPrimitive)]
117#[repr(u32)]
118enum ServiceField {
119 Schema = 0,
120 Name = 1,
121 Doc = 2,
122 Uuid = 3,
123 Version = 4,
124 Functions = 5,
125 Events = 6,
126 FunctionFallback = 7,
127 EventFallback = 8,
128}
129
130impl Tag for Service {}
131
132impl PrimaryTag for Service {
133 type Tag = Self;
134}
135
136impl Serialize<Self> for Service {
137 fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
138 serializer.serialize(&self)
139 }
140}
141
142impl Serialize<Service> for &Service {
143 fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
144 let mut serializer = serializer.serialize_struct2()?;
145
146 serializer.serialize::<tags::String>(ServiceField::Schema, &self.schema)?;
147 serializer.serialize::<tags::String>(ServiceField::Name, &self.name)?;
148 serializer.serialize_if_some::<tags::Option<tags::String>>(ServiceField::Doc, &self.doc)?;
149 serializer.serialize::<ServiceUuid>(ServiceField::Uuid, &self.uuid)?;
150 serializer.serialize::<tags::U32>(ServiceField::Version, &self.version)?;
151
152 serializer.serialize::<tags::Map<tags::U32, Function>>(
153 ServiceField::Functions,
154 &self.functions,
155 )?;
156
157 serializer.serialize::<tags::Map<tags::U32, Event>>(ServiceField::Events, &self.events)?;
158
159 serializer.serialize_if_some::<tags::Option<FunctionFallback>>(
160 ServiceField::FunctionFallback,
161 &self.function_fallback,
162 )?;
163
164 serializer.serialize_if_some::<tags::Option<EventFallback>>(
165 ServiceField::EventFallback,
166 &self.event_fallback,
167 )?;
168
169 serializer.finish()
170 }
171}
172
173impl Deserialize<Self> for Service {
174 fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
175 let mut deserializer = deserializer.deserialize_struct()?;
176
177 let mut schema = None;
178 let mut name = None;
179 let mut doc = None;
180 let mut uuid = None;
181 let mut version = None;
182 let mut functions = None;
183 let mut events = None;
184 let mut function_fallback = None;
185 let mut event_fallback = None;
186
187 while let Some(deserializer) = deserializer.deserialize()? {
188 match deserializer.try_id() {
189 Ok(ServiceField::Schema) => {
190 schema = deserializer.deserialize::<tags::String, _>().map(Some)?;
191 }
192
193 Ok(ServiceField::Name) => {
194 name = deserializer.deserialize::<tags::String, _>().map(Some)?;
195 }
196
197 Ok(ServiceField::Doc) => {
198 doc = deserializer.deserialize::<tags::Option<tags::String>, _>()?;
199 }
200
201 Ok(ServiceField::Uuid) => {
202 uuid = deserializer.deserialize::<ServiceUuid, _>().map(Some)?;
203 }
204
205 Ok(ServiceField::Version) => {
206 version = deserializer.deserialize::<tags::U32, _>().map(Some)?;
207 }
208
209 Ok(ServiceField::Functions) => {
210 functions = deserializer
211 .deserialize::<tags::Map<tags::U32, Function>, _>()
212 .map(Some)?;
213 }
214
215 Ok(ServiceField::Events) => {
216 events = deserializer
217 .deserialize::<tags::Map<tags::U32, Event>, _>()
218 .map(Some)?;
219 }
220
221 Ok(ServiceField::FunctionFallback) => {
222 function_fallback =
223 deserializer.deserialize::<tags::Option<FunctionFallback>, _>()?;
224 }
225
226 Ok(ServiceField::EventFallback) => {
227 event_fallback =
228 deserializer.deserialize::<tags::Option<EventFallback>, _>()?;
229 }
230
231 Err(_) => deserializer.skip()?,
232 }
233 }
234
235 deserializer.finish(Self {
236 schema: schema.ok_or(DeserializeError::InvalidSerialization)?,
237 name: name.ok_or(DeserializeError::InvalidSerialization)?,
238 doc,
239 uuid: uuid.ok_or(DeserializeError::InvalidSerialization)?,
240 version: version.ok_or(DeserializeError::InvalidSerialization)?,
241 functions: functions.ok_or(DeserializeError::InvalidSerialization)?,
242 events: events.ok_or(DeserializeError::InvalidSerialization)?,
243 function_fallback,
244 event_fallback,
245 })
246 }
247}