aldrin_core/introspection/
service.rs1use super::{Event, Function, LexicalId};
2use crate::error::{DeserializeError, SerializeError};
3use crate::ids::ServiceUuid;
4use crate::value_deserializer::{Deserialize, Deserializer};
5use crate::value_serializer::{Serialize, Serializer};
6use num_enum::{IntoPrimitive, TryFromPrimitive};
7use std::collections::BTreeMap;
8use uuid::{uuid, Uuid};
9
10#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
11pub struct Service {
12 schema: String,
13 name: String,
14 uuid: ServiceUuid,
15 version: u32,
16 functions: BTreeMap<u32, Function>,
17 events: BTreeMap<u32, Event>,
18 function_fallback: Option<String>,
19 event_fallback: Option<String>,
20}
21
22impl Service {
23 pub const NAMESPACE: Uuid = uuid!("de06b048-55f7-43b9-8d34-555795c2f4c6");
24
25 pub fn builder(
26 schema: impl Into<String>,
27 name: impl Into<String>,
28 uuid: ServiceUuid,
29 version: u32,
30 ) -> ServiceBuilder {
31 ServiceBuilder::new(schema, name, uuid, version)
32 }
33
34 pub fn lexical_id(&self) -> LexicalId {
35 LexicalId::service(&self.schema, &self.name)
36 }
37
38 pub fn schema(&self) -> &str {
39 &self.schema
40 }
41
42 pub fn name(&self) -> &str {
43 &self.name
44 }
45
46 pub fn uuid(&self) -> ServiceUuid {
47 self.uuid
48 }
49
50 pub fn version(&self) -> u32 {
51 self.version
52 }
53
54 pub fn functions(&self) -> &BTreeMap<u32, Function> {
55 &self.functions
56 }
57
58 pub fn events(&self) -> &BTreeMap<u32, Event> {
59 &self.events
60 }
61
62 pub fn function_fallback(&self) -> Option<&str> {
63 self.function_fallback.as_deref()
64 }
65
66 pub fn event_fallback(&self) -> Option<&str> {
67 self.event_fallback.as_deref()
68 }
69}
70
71#[derive(IntoPrimitive, TryFromPrimitive)]
72#[repr(u32)]
73enum ServiceField {
74 Schema = 0,
75 Name = 1,
76 Uuid = 2,
77 Version = 3,
78 Functions = 4,
79 Events = 5,
80 FunctionFallback = 6,
81 EventFallback = 7,
82}
83
84impl Serialize for Service {
85 fn serialize(&self, serializer: Serializer) -> Result<(), SerializeError> {
86 let num = 6
87 + (self.function_fallback.is_some() as usize)
88 + (self.event_fallback.is_some() as usize);
89 let mut serializer = serializer.serialize_struct(num)?;
90
91 serializer.serialize_field(ServiceField::Schema, &self.schema)?;
92 serializer.serialize_field(ServiceField::Name, &self.name)?;
93 serializer.serialize_field(ServiceField::Uuid, &self.uuid)?;
94 serializer.serialize_field(ServiceField::Version, &self.version)?;
95 serializer.serialize_field(ServiceField::Functions, &self.functions)?;
96 serializer.serialize_field(ServiceField::Events, &self.events)?;
97
98 if self.function_fallback.is_some() {
99 serializer.serialize_field(ServiceField::FunctionFallback, &self.function_fallback)?;
100 }
101
102 if self.event_fallback.is_some() {
103 serializer.serialize_field(ServiceField::EventFallback, &self.event_fallback)?;
104 }
105
106 serializer.finish()
107 }
108}
109
110impl Deserialize for Service {
111 fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
112 let mut deserializer = deserializer.deserialize_struct()?;
113
114 let mut schema = None;
115 let mut name = None;
116 let mut uuid = None;
117 let mut version = None;
118 let mut functions = None;
119 let mut events = None;
120 let mut function_fallback = None;
121 let mut event_fallback = None;
122
123 while deserializer.has_more_fields() {
124 let deserializer = deserializer.deserialize_field()?;
125
126 match deserializer.try_id()? {
127 ServiceField::Schema => schema = deserializer.deserialize().map(Some)?,
128 ServiceField::Name => name = deserializer.deserialize().map(Some)?,
129 ServiceField::Uuid => uuid = deserializer.deserialize().map(Some)?,
130 ServiceField::Version => version = deserializer.deserialize().map(Some)?,
131 ServiceField::Functions => functions = deserializer.deserialize().map(Some)?,
132 ServiceField::Events => events = deserializer.deserialize().map(Some)?,
133 ServiceField::FunctionFallback => function_fallback = deserializer.deserialize()?,
134 ServiceField::EventFallback => event_fallback = deserializer.deserialize()?,
135 }
136 }
137
138 deserializer.finish(Self {
139 schema: schema.ok_or(DeserializeError::InvalidSerialization)?,
140 name: name.ok_or(DeserializeError::InvalidSerialization)?,
141 uuid: uuid.ok_or(DeserializeError::InvalidSerialization)?,
142 version: version.ok_or(DeserializeError::InvalidSerialization)?,
143 functions: functions.ok_or(DeserializeError::InvalidSerialization)?,
144 events: events.ok_or(DeserializeError::InvalidSerialization)?,
145 function_fallback,
146 event_fallback,
147 })
148 }
149}
150
151#[derive(Debug, Clone)]
152pub struct ServiceBuilder {
153 schema: String,
154 name: String,
155 uuid: ServiceUuid,
156 version: u32,
157 functions: BTreeMap<u32, Function>,
158 events: BTreeMap<u32, Event>,
159 function_fallback: Option<String>,
160 event_fallback: Option<String>,
161}
162
163impl ServiceBuilder {
164 pub fn new(
165 schema: impl Into<String>,
166 name: impl Into<String>,
167 uuid: ServiceUuid,
168 version: u32,
169 ) -> Self {
170 Self {
171 schema: schema.into(),
172 name: name.into(),
173 uuid,
174 version,
175 functions: BTreeMap::new(),
176 events: BTreeMap::new(),
177 function_fallback: None,
178 event_fallback: None,
179 }
180 }
181
182 pub fn function(
183 mut self,
184 id: u32,
185 name: impl Into<String>,
186 args: Option<LexicalId>,
187 ok: Option<LexicalId>,
188 err: Option<LexicalId>,
189 ) -> Self {
190 self.functions
191 .insert(id, Function::new(id, name, args, ok, err));
192 self
193 }
194
195 pub fn event(
196 mut self,
197 id: u32,
198 name: impl Into<String>,
199 event_type: Option<LexicalId>,
200 ) -> Self {
201 self.events.insert(id, Event::new(id, name, event_type));
202 self
203 }
204
205 pub fn function_fallback(mut self, name: impl Into<String>) -> Self {
206 self.function_fallback = Some(name.into());
207 self
208 }
209
210 pub fn event_fallback(mut self, name: impl Into<String>) -> Self {
211 self.event_fallback = Some(name.into());
212 self
213 }
214
215 pub fn finish(self) -> Service {
216 Service {
217 schema: self.schema,
218 name: self.name,
219 uuid: self.uuid,
220 version: self.version,
221 functions: self.functions,
222 events: self.events,
223 function_fallback: self.function_fallback,
224 event_fallback: self.event_fallback,
225 }
226 }
227}