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}