aldrin_core/introspection/
enum_ty.rs1use super::{LexicalId, Variant};
2use crate::error::{DeserializeError, SerializeError};
3use crate::value_deserializer::{Deserialize, Deserializer};
4use crate::value_serializer::{Serialize, Serializer};
5use num_enum::{IntoPrimitive, TryFromPrimitive};
6use std::collections::BTreeMap;
7use uuid::{uuid, Uuid};
8
9#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
10pub struct Enum {
11 schema: String,
12 name: String,
13 variants: BTreeMap<u32, Variant>,
14 fallback: Option<String>,
15}
16
17impl Enum {
18 pub const NAMESPACE: Uuid = uuid!("642bf73e-991f-406a-b55a-ce914d77480b");
19
20 pub fn builder(schema: impl Into<String>, name: impl Into<String>) -> EnumBuilder {
21 EnumBuilder::new(schema, name)
22 }
23
24 pub fn lexical_id(&self) -> LexicalId {
25 LexicalId::custom(&self.schema, &self.name)
26 }
27
28 pub fn schema(&self) -> &str {
29 &self.schema
30 }
31
32 pub fn name(&self) -> &str {
33 &self.name
34 }
35
36 pub fn variants(&self) -> &BTreeMap<u32, Variant> {
37 &self.variants
38 }
39
40 pub fn fallback(&self) -> Option<&str> {
41 self.fallback.as_deref()
42 }
43}
44
45#[derive(IntoPrimitive, TryFromPrimitive)]
46#[repr(u32)]
47enum EnumField {
48 Schema = 0,
49 Name = 1,
50 Variants = 2,
51 Fallback = 3,
52}
53
54impl Serialize for Enum {
55 fn serialize(&self, serializer: Serializer) -> Result<(), SerializeError> {
56 let num = 3 + (self.fallback.is_some() as usize);
57 let mut serializer = serializer.serialize_struct(num)?;
58
59 serializer.serialize_field(EnumField::Schema, &self.schema)?;
60 serializer.serialize_field(EnumField::Name, &self.name)?;
61 serializer.serialize_field(EnumField::Variants, &self.variants)?;
62
63 if let Some(ref fallback) = self.fallback {
64 serializer.serialize_field(EnumField::Fallback, &Some(fallback))?;
65 }
66
67 serializer.finish()
68 }
69}
70
71impl Deserialize for Enum {
72 fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
73 let mut deserializer = deserializer.deserialize_struct()?;
74
75 let mut schema = None;
76 let mut name = None;
77 let mut variants = None;
78 let mut fallback = None;
79
80 while deserializer.has_more_fields() {
81 let deserializer = deserializer.deserialize_field()?;
82
83 match deserializer.try_id()? {
84 EnumField::Schema => schema = deserializer.deserialize().map(Some)?,
85 EnumField::Name => name = deserializer.deserialize().map(Some)?,
86 EnumField::Variants => variants = deserializer.deserialize().map(Some)?,
87 EnumField::Fallback => fallback = deserializer.deserialize()?,
88 }
89 }
90
91 deserializer.finish(Self {
92 schema: schema.ok_or(DeserializeError::InvalidSerialization)?,
93 name: name.ok_or(DeserializeError::InvalidSerialization)?,
94 variants: variants.ok_or(DeserializeError::InvalidSerialization)?,
95 fallback,
96 })
97 }
98}
99
100#[derive(Debug, Clone)]
101pub struct EnumBuilder {
102 schema: String,
103 name: String,
104 variants: BTreeMap<u32, Variant>,
105 fallback: Option<String>,
106}
107
108impl EnumBuilder {
109 pub fn new(schema: impl Into<String>, name: impl Into<String>) -> Self {
110 Self {
111 schema: schema.into(),
112 name: name.into(),
113 variants: BTreeMap::new(),
114 fallback: None,
115 }
116 }
117
118 pub fn variant(
119 mut self,
120 id: u32,
121 name: impl Into<String>,
122 variant_type: Option<LexicalId>,
123 ) -> Self {
124 self.variants
125 .insert(id, Variant::new(id, name, variant_type));
126 self
127 }
128
129 pub fn variant_with_type(
130 self,
131 id: u32,
132 name: impl Into<String>,
133 variant_type: LexicalId,
134 ) -> Self {
135 self.variant(id, name, Some(variant_type))
136 }
137
138 pub fn unit_variant(self, id: u32, name: impl Into<String>) -> Self {
139 self.variant(id, name, None)
140 }
141
142 pub fn fallback(mut self, name: impl Into<String>) -> Self {
143 self.fallback = Some(name.into());
144 self
145 }
146
147 pub fn finish(self) -> Enum {
148 Enum {
149 schema: self.schema,
150 name: self.name,
151 variants: self.variants,
152 fallback: self.fallback,
153 }
154 }
155}