Skip to main content

fixed_json/
model.rs

1use crate::{Error, Result};
2
3pub const JSON_ATTR_MAX: usize = 31;
4pub const JSON_VAL_MAX: usize = 512;
5
6#[derive(Clone, Copy)]
7pub struct EnumValue<'a> {
8    pub name: &'a str,
9    pub value: i32,
10}
11
12#[derive(Clone, Copy)]
13pub enum DefaultValue<'a> {
14    None,
15    Integer(i32),
16    UInteger(u32),
17    Short(i16),
18    UShort(u16),
19    Real(f64),
20    Boolean(bool),
21    Character(u8),
22    Check(&'a str),
23}
24
25pub enum Target<'a, T> {
26    One(&'a mut T),
27    Many(&'a mut [T]),
28}
29
30impl<T: Copy> Target<'_, T> {
31    #[inline]
32    pub(crate) fn set(&mut self, offset: usize, value: T) -> Result<()> {
33        match self {
34            Target::One(target) if offset == 0 => {
35                **target = value;
36                Ok(())
37            }
38            Target::Many(targets) => {
39                *targets.get_mut(offset).ok_or(Error::SubTooLong)? = value;
40                Ok(())
41            }
42            Target::One(_) => Ok(()),
43        }
44    }
45}
46
47pub type TargetI32<'a> = Target<'a, i32>;
48pub type TargetU32<'a> = Target<'a, u32>;
49pub type TargetI16<'a> = Target<'a, i16>;
50pub type TargetU16<'a> = Target<'a, u16>;
51pub type TargetF64<'a> = Target<'a, f64>;
52pub type TargetBool<'a> = Target<'a, bool>;
53pub type TargetChar<'a> = Target<'a, u8>;
54
55pub enum AttrKind<'a> {
56    Integer(TargetI32<'a>),
57    UInteger(TargetU32<'a>),
58    Real(TargetF64<'a>),
59    String(&'a mut [u8]),
60    Boolean(TargetBool<'a>),
61    Character(TargetChar<'a>),
62    Time(TargetF64<'a>),
63    Object(&'a mut [Attr<'a>]),
64    Array(Array<'a>),
65    Check(&'a str),
66    Ignore,
67    Short(TargetI16<'a>),
68    UShort(TargetU16<'a>),
69}
70
71pub struct Attr<'a> {
72    pub name: &'a str,
73    pub kind: AttrKind<'a>,
74    pub default: DefaultValue<'a>,
75    pub map: Option<&'a [EnumValue<'a>]>,
76    pub nodefault: bool,
77}
78
79impl<'a> Attr<'a> {
80    #[inline]
81    pub fn integer(name: &'a str, target: &'a mut i32) -> Self {
82        Self::new(name, AttrKind::Integer(TargetI32::One(target)))
83    }
84
85    #[inline]
86    pub fn integers(name: &'a str, target: &'a mut [i32]) -> Self {
87        Self::new(name, AttrKind::Integer(TargetI32::Many(target)))
88    }
89
90    #[inline]
91    pub fn uinteger(name: &'a str, target: &'a mut u32) -> Self {
92        Self::new(name, AttrKind::UInteger(TargetU32::One(target)))
93    }
94
95    #[inline]
96    pub fn uintegers(name: &'a str, target: &'a mut [u32]) -> Self {
97        Self::new(name, AttrKind::UInteger(TargetU32::Many(target)))
98    }
99
100    #[inline]
101    pub fn short(name: &'a str, target: &'a mut i16) -> Self {
102        Self::new(name, AttrKind::Short(TargetI16::One(target)))
103    }
104
105    #[inline]
106    pub fn shorts(name: &'a str, target: &'a mut [i16]) -> Self {
107        Self::new(name, AttrKind::Short(TargetI16::Many(target)))
108    }
109
110    #[inline]
111    pub fn ushort(name: &'a str, target: &'a mut u16) -> Self {
112        Self::new(name, AttrKind::UShort(TargetU16::One(target)))
113    }
114
115    #[inline]
116    pub fn ushorts(name: &'a str, target: &'a mut [u16]) -> Self {
117        Self::new(name, AttrKind::UShort(TargetU16::Many(target)))
118    }
119
120    #[inline]
121    pub fn real(name: &'a str, target: &'a mut f64) -> Self {
122        Self::new(name, AttrKind::Real(TargetF64::One(target)))
123    }
124
125    #[inline]
126    pub fn reals(name: &'a str, target: &'a mut [f64]) -> Self {
127        Self::new(name, AttrKind::Real(TargetF64::Many(target)))
128    }
129
130    #[inline]
131    pub fn string(name: &'a str, target: &'a mut [u8]) -> Self {
132        Self::new(name, AttrKind::String(target))
133    }
134
135    #[inline]
136    pub fn boolean(name: &'a str, target: &'a mut bool) -> Self {
137        Self::new(name, AttrKind::Boolean(TargetBool::One(target)))
138    }
139
140    #[inline]
141    pub fn booleans(name: &'a str, target: &'a mut [bool]) -> Self {
142        Self::new(name, AttrKind::Boolean(TargetBool::Many(target)))
143    }
144
145    #[inline]
146    pub fn character(name: &'a str, target: &'a mut u8) -> Self {
147        Self::new(name, AttrKind::Character(TargetChar::One(target)))
148    }
149
150    #[inline]
151    pub fn characters(name: &'a str, target: &'a mut [u8]) -> Self {
152        Self::new(name, AttrKind::Character(TargetChar::Many(target)))
153    }
154
155    #[inline]
156    pub fn time(name: &'a str, target: &'a mut f64) -> Self {
157        Self::new(name, AttrKind::Time(TargetF64::One(target)))
158    }
159
160    #[inline]
161    pub fn object(name: &'a str, attrs: &'a mut [Attr<'a>]) -> Self {
162        Self::new(name, AttrKind::Object(attrs))
163    }
164
165    #[inline]
166    pub fn array(name: &'a str, array: Array<'a>) -> Self {
167        Self::new(name, AttrKind::Array(array))
168    }
169
170    #[inline]
171    pub fn check(name: &'a str, expected: &'a str) -> Self {
172        let mut attr = Self::new(name, AttrKind::Check(expected));
173        attr.default = DefaultValue::Check(expected);
174        attr
175    }
176
177    #[inline]
178    pub fn ignore_any() -> Self {
179        Self::new("", AttrKind::Ignore)
180    }
181
182    #[inline]
183    pub fn with_default(mut self, default: DefaultValue<'a>) -> Self {
184        self.default = default;
185        self
186    }
187
188    #[inline]
189    pub fn with_map(mut self, map: &'a [EnumValue<'a>]) -> Self {
190        self.map = Some(map);
191        self
192    }
193
194    #[inline]
195    pub fn nodefault(mut self) -> Self {
196        self.nodefault = true;
197        self
198    }
199
200    #[inline]
201    fn new(name: &'a str, kind: AttrKind<'a>) -> Self {
202        Self {
203            name,
204            kind,
205            default: DefaultValue::None,
206            map: None,
207            nodefault: false,
208        }
209    }
210}
211
212pub enum Array<'a> {
213    Strings {
214        store: &'a mut [&'a mut [u8]],
215        count: Option<&'a mut usize>,
216    },
217    Integers {
218        store: &'a mut [i32],
219        count: Option<&'a mut usize>,
220    },
221    UIntegers {
222        store: &'a mut [u32],
223        count: Option<&'a mut usize>,
224    },
225    Shorts {
226        store: &'a mut [i16],
227        count: Option<&'a mut usize>,
228    },
229    UShorts {
230        store: &'a mut [u16],
231        count: Option<&'a mut usize>,
232    },
233    Reals {
234        store: &'a mut [f64],
235        count: Option<&'a mut usize>,
236    },
237    Booleans {
238        store: &'a mut [bool],
239        count: Option<&'a mut usize>,
240    },
241    Objects {
242        attrs: &'a mut [Attr<'a>],
243        maxlen: usize,
244        count: Option<&'a mut usize>,
245    },
246    StructObjects {
247        maxlen: usize,
248        count: Option<&'a mut usize>,
249        parser: &'a mut dyn FnMut(&str, usize) -> Result<usize>,
250    },
251}
252
253#[cfg(test)]
254mod tests {
255    use super::Target;
256
257    #[test]
258    fn single_target_only_accepts_offset_zero() {
259        let mut value = 7;
260        let mut target = Target::One(&mut value);
261
262        target.set(0, 11).unwrap();
263        target.set(1, 99).unwrap();
264
265        assert_eq!(value, 11);
266    }
267
268    #[test]
269    fn many_target_writes_by_offset_and_rejects_overflow() {
270        let mut values = [0, 1, 2];
271        let mut target = Target::Many(&mut values);
272
273        target.set(2, 9).unwrap();
274        let err = target.set(3, 10).unwrap_err();
275
276        assert_eq!(values, [0, 1, 9]);
277        assert_eq!(err as i32, crate::Error::SubTooLong as i32);
278    }
279}