1use super::*;
2
3#[repr(u8)]
7#[derive(Copy, Clone, StableAbi)]
8#[sabi(unsafe_sabi_opaque_fields)]
9pub enum MonoTLData {
10 Primitive(TLPrimitive),
12 Opaque,
14 Struct {
16 fields: CompTLFields,
18 },
19 Union {
21 fields: CompTLFields,
23 },
24 Enum(MonoTLEnum),
26 PrefixType(MonoTLPrefixType),
28}
29
30impl MonoTLData {
31 pub const EMPTY: Self = MonoTLData::Struct {
33 fields: CompTLFields::EMPTY,
34 };
35
36 pub const fn struct_(fields: RSlice<'static, CompTLField>) -> Self {
38 MonoTLData::Struct {
39 fields: CompTLFields::from_fields(fields),
40 }
41 }
42
43 #[doc(hidden)]
44 pub const fn derive_struct(fields: CompTLFields) -> Self {
45 MonoTLData::Struct { fields }
46 }
47
48 pub const fn union_(fields: RSlice<'static, CompTLField>) -> Self {
50 MonoTLData::Union {
51 fields: CompTLFields::from_fields(fields),
52 }
53 }
54
55 #[doc(hidden)]
56 pub const fn derive_union(fields: CompTLFields) -> Self {
57 MonoTLData::Union { fields }
58 }
59
60 pub const fn prefix_type(
62 first_suffix_field: usize,
63 conditional_prefix_fields: FieldConditionality,
64 fields: RSlice<'static, CompTLField>,
65 ) -> Self {
66 MonoTLData::PrefixType(MonoTLPrefixType {
67 first_suffix_field: first_suffix_field as u8,
68 conditional_prefix_fields,
69 fields: CompTLFields::from_fields(fields),
70 })
71 }
72
73 pub const fn struct_derive(fields: CompTLFields) -> Self {
75 MonoTLData::Struct { fields }
76 }
77
78 pub const fn union_derive(fields: CompTLFields) -> Self {
80 MonoTLData::Union { fields }
81 }
82
83 pub const fn prefix_type_derive(
85 first_suffix_field: usize,
86 conditional_prefix_fields: u64,
87 fields: CompTLFields,
88 ) -> Self {
89 MonoTLData::PrefixType(MonoTLPrefixType {
90 first_suffix_field: first_suffix_field as u8,
91 conditional_prefix_fields: FieldConditionality::from_u64(conditional_prefix_fields),
92 fields,
93 })
94 }
95
96 pub const fn as_discriminant(&self) -> TLDataDiscriminant {
99 match self {
100 MonoTLData::Primitive { .. } => TLDataDiscriminant::Primitive,
101 MonoTLData::Opaque { .. } => TLDataDiscriminant::Opaque,
102 MonoTLData::Struct { .. } => TLDataDiscriminant::Struct,
103 MonoTLData::Union { .. } => TLDataDiscriminant::Union,
104 MonoTLData::Enum { .. } => TLDataDiscriminant::Enum,
105 MonoTLData::PrefixType { .. } => TLDataDiscriminant::PrefixType,
106 }
107 }
108
109 pub(super) const fn to_primitive(self) -> Option<TLPrimitive> {
110 match self {
111 MonoTLData::Primitive(x) => Some(x),
112 _ => None,
113 }
114 }
115
116 pub fn expand(
123 self,
124 generic: GenericTLData,
125 shared_vars: &'static SharedVars,
126 ) -> Result<TLData, MismatchedTLDataVariant> {
127 Ok(match (self, generic) {
128 (MonoTLData::Primitive(prim), GenericTLData::Primitive) => TLData::Primitive(prim),
129 (MonoTLData::Opaque, GenericTLData::Opaque) => TLData::Opaque,
130 (MonoTLData::Struct { fields }, GenericTLData::Struct) => TLData::Struct {
131 fields: fields.expand(shared_vars),
132 },
133 (MonoTLData::Union { fields }, GenericTLData::Union) => TLData::Union {
134 fields: fields.expand(shared_vars),
135 },
136 (MonoTLData::Enum(nongeneric), GenericTLData::Enum(generic)) => {
137 TLData::Enum(nongeneric.expand(generic, shared_vars))
138 }
139 (MonoTLData::PrefixType(nongeneric), GenericTLData::PrefixType(generic)) => {
140 TLData::PrefixType(nongeneric.expand(generic, shared_vars))
141 }
142 _ => {
143 return Err(MismatchedTLDataVariant {
144 nongeneric: self.as_discriminant(),
145 generic: generic.as_discriminant(),
146 })
147 }
148 })
149 }
150}
151
152#[derive(Debug, Clone)]
157pub struct MismatchedTLDataVariant {
158 nongeneric: TLDataDiscriminant,
159 generic: TLDataDiscriminant,
160}
161
162impl Display for MismatchedTLDataVariant {
163 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
164 writeln!(
165 f,
166 "Error combining TLData::{:?} and GenericTLData::{:?}",
167 self.nongeneric, self.generic,
168 )
169 }
170}
171
172#[repr(u8)]
176#[derive(Debug, Copy, Clone, PartialEq, Eq, StableAbi)]
177#[sabi(unsafe_sabi_opaque_fields)]
178pub enum TLDataDiscriminant {
179 Primitive,
181 Opaque,
183 Struct,
185 Union,
187 Enum,
189 PrefixType,
191}
192
193#[repr(C)]
197#[derive(Copy, Clone, StableAbi)]
198#[sabi(unsafe_sabi_opaque_fields)]
199pub enum GenericTLData {
200 Primitive,
202 Opaque,
204 Struct,
206 Union,
208 Enum(GenericTLEnum),
210 PrefixType(GenericTLPrefixType),
212}
213
214impl GenericTLData {
215 pub const fn as_discriminant(&self) -> TLDataDiscriminant {
218 match self {
219 GenericTLData::Primitive { .. } => TLDataDiscriminant::Primitive,
220 GenericTLData::Opaque { .. } => TLDataDiscriminant::Opaque,
221 GenericTLData::Struct { .. } => TLDataDiscriminant::Struct,
222 GenericTLData::Union { .. } => TLDataDiscriminant::Union,
223 GenericTLData::Enum { .. } => TLDataDiscriminant::Enum,
224 GenericTLData::PrefixType { .. } => TLDataDiscriminant::PrefixType,
225 }
226 }
227
228 #[doc(hidden)]
229 pub const fn prefix_type_derive(accessible_fields: FieldAccessibility) -> Self {
230 GenericTLData::PrefixType(GenericTLPrefixType { accessible_fields })
231 }
232}
233
234#[derive(Debug, Copy, Clone, PartialEq, Eq)]
239pub enum TLData {
240 Primitive(TLPrimitive),
242 Opaque,
248 Struct {
250 fields: TLFields,
252 },
253 Union {
255 fields: TLFields,
257 },
258 Enum(TLEnum),
260 PrefixType(TLPrefixType),
262}
263
264impl Display for TLData {
265 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
266 match self {
267 TLData::Primitive(prim) => {
268 writeln!(f, "Primitive:{:?}", prim)?;
269 }
270 TLData::Opaque => {
271 writeln!(f, "Opaque data")?;
272 }
273 TLData::Struct { fields } => {
274 writeln!(
275 f,
276 "Struct with Fields:\n{}",
277 fields.to_string().left_padder(4)
278 )?;
279 }
280 TLData::Union { fields } => {
281 writeln!(
282 f,
283 "Union with Fields:\n{}",
284 fields.to_string().left_padder(4)
285 )?;
286 }
287 TLData::Enum(enum_) => {
288 writeln!(f, "Enum:")?;
289 Display::fmt(enum_, f)?;
290 }
291 TLData::PrefixType(prefix) => {
292 writeln!(f, "Prefix type:")?;
293 Display::fmt(prefix, f)?;
294 }
295 }
296 Ok(())
297 }
298}