1pub mod byte_display;
2pub mod visitor;
3use core::panic;
4use std::fmt::Debug;
5
6use borsh::{BorshDeserialize, BorshSerialize};
7pub use byte_display::ByteDisplay;
8#[cfg(feature = "serde")]
9use serde::{de::DeserializeOwned, Deserialize, Serialize};
10
11use crate::schema::{IndexLinking, Link, OverrideSchema, Primitive};
12
13macro_rules! macro_for_ints {
14 ($macro:ident) => {
15 $macro!(u8);
16 $macro!(u16);
17 $macro!(u32);
18 $macro!(u64);
19 $macro!(u128);
20 $macro!(i8);
21 $macro!(i16);
22 $macro!(i32);
23 $macro!(i64);
24 $macro!(i128);
25 };
26}
27pub(crate) use macro_for_ints;
28
29pub trait LinkingScheme: Clone + Debug {
30 #[cfg(not(feature = "serde"))]
33 type TypeLink: Clone + Debug + PartialEq + Eq + BorshSerialize + BorshDeserialize;
34 #[cfg(feature = "serde")]
35 type TypeLink: Clone
36 + Debug
37 + PartialEq
38 + Eq
39 + BorshSerialize
40 + BorshDeserialize
41 + Serialize
42 + DeserializeOwned;
43}
44
45#[derive(Clone, Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
46#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
47pub enum Ty<L: LinkingScheme> {
48 Enum(Enum<L>),
49 Struct(Struct<L>),
50 Tuple(Tuple<L>),
51 Option {
52 value: L::TypeLink,
53 },
54 Integer(IntegerType, IntegerDisplay),
55 ByteArray {
56 len: usize,
57 display: ByteDisplay,
58 },
59 Float32,
60 Float64,
61 String,
62 Boolean,
63 Skip {
64 len: usize,
65 },
66 ByteVec {
67 display: ByteDisplay,
68 },
69 Array {
70 len: usize,
71 value: L::TypeLink,
72 },
73 Vec {
74 value: L::TypeLink,
75 },
76 Map {
77 key: L::TypeLink,
78 value: L::TypeLink,
79 },
80}
81
82impl<L: LinkingScheme> Ty<L> {
83 pub fn is_skip(&self) -> bool {
85 matches!(self, Ty::Skip { .. })
86 }
87}
88
89impl Ty<IndexLinking> {
90 pub fn fill_next_placholder(&mut self, child: Link) {
92 let err_msg =
93 format!("Called `fill_next_placholder` on a type with no placeholders: {self:?}");
94 match self {
95 Ty::Enum(e) => {
96 e.variants
97 .iter_mut()
98 .find(|v| v.value == Some(Link::Placeholder))
99 .expect(&err_msg).value = Some(child);
100 }
101 Ty::Struct(s) => {
102 s.fields
103 .iter_mut()
104 .find(|field| field.value == Link::Placeholder)
105 .expect(&err_msg)
106 .value = child;
107 }
108 Ty::Tuple(t) => {
109 t.fields
110 .iter_mut()
111 .find(|field| field.value == Link::Placeholder)
112 .expect(&err_msg)
113 .value = child;
114 }
115 Ty::Option { value } => if *value == Link::Placeholder {
116 *value = child;
117 } else {
118 panic!("{}", err_msg);
119 }
120 Ty::Array { value, .. } => {
121 if *value == Link::Placeholder {
122 *value = child;
123 } else {
124 panic!("{}", err_msg);
125 }
126 }
127 Ty::Vec { value } => if *value == Link::Placeholder {
128 *value = child;
129 } else {
130 panic!("{}", err_msg);
131 }
132 Ty::Map { key, value } => if *key == Link::Placeholder {
133 *key = child;
134 } else if *value == Link::Placeholder {
135 *value = child;
136 } else {
137 panic!("{}", err_msg);
138 }
139 _ => panic!(
140 "Tried to fill a placholder on a type with no children. Only Vec, Tuple, Option, Array, Struct and Map types have children. Self: {:?}",
141 self
142 ),
143 }
144 }
145}
146
147impl<L: LinkingScheme> Ty<L> {
148 pub fn is_primitive(&self) -> bool {
149 match self {
151 Ty::Enum(_)
152 | Ty::Struct(_)
153 | Ty::Tuple(_)
154 | Ty::Option { .. }
155 | Ty::Array { .. }
156 | Ty::Vec { .. }
157 | Ty::Map { .. } => false,
158 Ty::Integer(_, _)
159 | Ty::ByteArray { .. }
160 | Ty::ByteVec { .. }
161 | Ty::String
162 | Ty::Float32
163 | Ty::Float64
164 | Ty::Boolean
165 | Ty::Skip { .. } => true,
166 }
167 }
168
169 pub fn parent_byte_references(&self) -> Vec<(usize, usize)> {
170 match self {
171 Ty::Integer(
172 _,
173 IntegerDisplay::FixedPoint(FixedPointDisplay::FromSiblingField {
174 field_index,
175 byte_offset,
176 }),
177 ) => vec![(*field_index, *byte_offset)],
178 _ => Vec::new(),
179 }
180 }
181}
182
183#[derive(Clone, Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
187#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
188pub struct EnumVariant<L: LinkingScheme> {
189 pub name: String,
190 pub discriminant: u8,
191 pub template: Option<String>,
192 pub value: Option<L::TypeLink>,
193}
194
195#[derive(Clone, Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
196#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
197pub struct Enum<L: LinkingScheme> {
198 pub type_name: String,
199 pub variants: Vec<EnumVariant<L>>,
200 pub hide_tag: bool,
202}
203
204#[derive(Clone, Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
205#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
206pub struct Struct<L: LinkingScheme> {
207 pub type_name: String,
208 pub template: Option<String>,
209 pub peekable: bool,
210 pub fields: Vec<NamedField<L>>,
211}
212
213#[derive(Clone, Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
214#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
215pub struct Tuple<L: LinkingScheme> {
216 pub template: Option<String>,
217 pub peekable: bool,
218 pub fields: Vec<UnnamedField<L>>,
219}
220
221#[derive(Clone, Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
222#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
223pub struct NamedField<L: LinkingScheme> {
224 pub display_name: String,
225 pub silent: bool,
226 pub value: L::TypeLink,
227 pub doc: String,
228}
229
230#[derive(Clone, Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
231#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
232pub struct UnnamedField<L: LinkingScheme> {
233 pub value: L::TypeLink,
234 pub silent: bool,
235 pub doc: String,
236}
237
238#[derive(Debug, Clone, Copy, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
239#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
240#[allow(non_camel_case_types)]
241pub enum IntegerType {
242 i8,
243 i16,
244 i32,
245 i64,
246 i128,
247 u8,
248 u16,
249 u32,
250 u64,
251 u128,
252}
253
254impl IntegerType {
255 pub fn size(&self) -> usize {
256 match self {
257 IntegerType::i8 => core::mem::size_of::<i8>(),
258 IntegerType::i16 => core::mem::size_of::<i16>(),
259 IntegerType::i32 => core::mem::size_of::<i32>(),
260 IntegerType::i64 => core::mem::size_of::<i64>(),
261 IntegerType::i128 => core::mem::size_of::<i128>(),
262 IntegerType::u8 => core::mem::size_of::<u8>(),
263 IntegerType::u16 => core::mem::size_of::<u16>(),
264 IntegerType::u32 => core::mem::size_of::<u32>(),
265 IntegerType::u64 => core::mem::size_of::<u64>(),
266 IntegerType::u128 => core::mem::size_of::<u128>(),
267 }
268 }
269}
270
271#[derive(Debug, Clone, Copy, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
272#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
273pub enum FixedPointDisplay {
274 Decimals(u8),
275 FromSiblingField {
276 field_index: usize,
277 byte_offset: usize,
278 },
279}
280
281#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, BorshSerialize, BorshDeserialize)]
282#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
283pub enum IntegerDisplay {
284 Hex,
285 #[default]
286 Decimal,
287 FixedPoint(FixedPointDisplay),
288}
289
290pub trait IntegerDisplayable {
291 fn integer_type() -> IntegerType;
292
293 fn with_display(display: IntegerDisplay) -> Link {
294 Link::Immediate(Primitive::Integer(Self::integer_type(), display))
295 }
296}
297
298macro_rules! integer_displayable {
299 ($t:ident) => {
300 impl IntegerDisplayable for $t {
301 fn integer_type() -> IntegerType {
302 IntegerType::$t
303 }
304 }
305 };
306}
307macro_for_ints!(integer_displayable);
308
309pub trait ByteDisplayable {
310 fn with_display(display: ByteDisplay) -> Link {
311 Link::Immediate(Primitive::ByteVec { display })
312 }
313}
314
315impl<T: OverrideSchema> ByteDisplayable for T
317where
318 T::Output: ByteDisplayable,
319{
320 fn with_display(display: ByteDisplay) -> Link {
321 T::Output::with_display(display)
322 }
323}
324
325impl ByteDisplayable for Vec<u8> {
326 fn with_display(display: ByteDisplay) -> Link {
327 Link::Immediate(Primitive::ByteVec { display })
328 }
329}
330
331impl<const N: usize> ByteDisplayable for [u8; N] {
332 fn with_display(display: ByteDisplay) -> Link {
333 Link::Immediate(Primitive::ByteArray { len: N, display })
334 }
335}
336
337#[derive(Debug, Clone, PartialEq, Eq, Default, BorshSerialize, BorshDeserialize)]
338#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
339pub struct ContainerSerdeMetadata {
340 pub name: String,
341 pub fields_or_variants: Vec<FieldOrVariantSerdeMetadata>,
342}
343
344#[derive(Debug, Clone, PartialEq, Eq, Default, BorshSerialize, BorshDeserialize)]
345#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
346pub struct FieldOrVariantSerdeMetadata {
347 pub name: String,
348}