1pub use super::OctetStr;
4use super::{
5 map, take, take_byte,
6 tlf::{Ty, TypeLengthField},
7 NumberFormatter, OctetStrFormatter, ParseError, ResTy, SmlParse, SmlParseTlf,
8};
9
10#[derive(PartialEq, Eq, Clone)]
11pub struct OpenResponse<'i> {
13 pub codepage: Option<OctetStr<'i>>,
15 pub client_id: Option<OctetStr<'i>>,
17 pub req_file_id: OctetStr<'i>,
19 pub server_id: OctetStr<'i>,
21 pub ref_time: Option<Time>,
23 pub sml_version: Option<u8>,
25}
26
27impl<'i> SmlParseTlf<'i> for OpenResponse<'i> {
28 fn check_tlf(tlf: &TypeLengthField) -> bool {
29 *tlf == TypeLengthField::new(Ty::ListOf, 6usize as u32)
30 }
31
32 fn parse_with_tlf(input: &'i [u8], _tlf: &TypeLengthField) -> ResTy<'i, Self> {
33 let (input, codepage) = <Option<OctetStr<'i>>>::parse(input)?;
34 let (input, client_id) = <Option<OctetStr<'i>>>::parse(input)?;
35 let (input, req_file_id) = <OctetStr<'i>>::parse(input)?;
36 let (input, server_id) = <OctetStr<'i>>::parse(input)?;
37 let (input, ref_time) = <Option<Time>>::parse(input)?;
38 let (input, sml_version) = <Option<u8>>::parse(input)?;
39 let val = OpenResponse {
40 codepage,
41 client_id,
42 req_file_id,
43 server_id,
44 ref_time,
45 sml_version,
46 };
47 Ok((input, val))
48 }
49}
50
51impl<'i> core::fmt::Debug for OpenResponse<'i> {
52 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
53 let mut x = f.debug_struct("OpenResponse");
54 if let Some(e) = &self.codepage {
55 x.field("codepage", &OctetStrFormatter(e));
56 }
57 if let Some(e) = &self.client_id {
58 x.field("client_id", &OctetStrFormatter(e));
59 }
60 x.field("req_file_id", &OctetStrFormatter(self.req_file_id));
61 x.field("server_id", &OctetStrFormatter(self.server_id));
62 if let Some(e) = &self.ref_time {
63 x.field("ref_time", &e);
64 }
65 if let Some(e) = &self.sml_version {
66 x.field("sml_version", &e);
67 }
68 x.finish()
69 }
70}
71
72#[derive(PartialEq, Eq, Clone)]
73pub struct ListEntry<'i> {
75 pub obj_name: OctetStr<'i>,
77 pub status: Option<Status>,
79 pub val_time: Option<Time>,
81 pub unit: Option<Unit>,
83 pub scaler: Option<i8>,
85 pub value: Value<'i>,
87 pub value_signature: Option<Signature<'i>>,
89}
90
91impl<'i> SmlParseTlf<'i> for ListEntry<'i> {
92 fn check_tlf(tlf: &TypeLengthField) -> bool {
93 *tlf == TypeLengthField::new(Ty::ListOf, 7usize as u32)
94 }
95
96 fn parse_with_tlf(input: &'i [u8], _tlf: &TypeLengthField) -> ResTy<'i, Self> {
97 let (input, obj_name) = <OctetStr<'i>>::parse(input)?;
98 let (input, status) = <Option<Status>>::parse(input)?;
99 let (input, val_time) = <Option<Time>>::parse(input)?;
100 let (input, unit) = <Option<Unit>>::parse(input)?;
101 let (input, scaler) = <Option<i8>>::parse(input)?;
102 let (input, value) = <Value<'i>>::parse(input)?;
103 let (input, value_signature) = <Option<Signature<'i>>>::parse(input)?;
104 let val = ListEntry {
105 obj_name,
106 status,
107 val_time,
108 unit,
109 scaler,
110 value,
111 value_signature,
112 };
113 Ok((input, val))
114 }
115}
116
117impl<'i> core::fmt::Debug for ListEntry<'i> {
118 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
119 let mut x = f.debug_struct("ListEntry");
120 x.field("obj_name", &OctetStrFormatter(self.obj_name));
121 if let Some(e) = &self.status {
122 x.field("status", &e);
123 }
124 if let Some(e) = &self.val_time {
125 x.field("val_time", &e);
126 }
127 if let Some(e) = &self.unit {
128 x.field("unit", &e);
129 }
130 if let Some(e) = &self.scaler {
131 x.field("scaler", &e);
132 }
133 x.field("value", &self.value);
134 if let Some(e) = &self.value_signature {
135 x.field("value_signature", &e);
136 }
137 x.finish()
138 }
139}
140
141#[derive(PartialEq, Eq, Clone)]
142#[allow(missing_docs)]
144pub enum Value<'i> {
145 Bool(bool),
146 Bytes(OctetStr<'i>),
147 I8(i8),
148 I16(i16),
149 I32(i32),
150 I64(i64),
151 U8(u8),
152 U16(u16),
153 U32(u32),
154 U64(u64),
155 List(ListType),
156}
157
158impl<'i> SmlParseTlf<'i> for Value<'i> {
159 fn check_tlf(_tlf: &TypeLengthField) -> bool {
160 true
161 }
162
163 fn parse_with_tlf(input: &'i [u8], tlf: &TypeLengthField) -> ResTy<'i, Self> {
164 match tlf {
165 tlf if <bool>::check_tlf(tlf) => map(<bool>::parse_with_tlf(input, tlf), Self::Bool),
166 tlf if <OctetStr<'i>>::check_tlf(tlf) => {
167 map(<OctetStr<'i>>::parse_with_tlf(input, tlf), Self::Bytes)
168 }
169 tlf if <i8>::check_tlf(tlf) => map(<i8>::parse_with_tlf(input, tlf), Self::I8),
170 tlf if <i16>::check_tlf(tlf) => map(<i16>::parse_with_tlf(input, tlf), Self::I16),
171 tlf if <i32>::check_tlf(tlf) => map(<i32>::parse_with_tlf(input, tlf), Self::I32),
172 tlf if <i64>::check_tlf(tlf) => map(<i64>::parse_with_tlf(input, tlf), Self::I64),
173 tlf if <u8>::check_tlf(tlf) => map(<u8>::parse_with_tlf(input, tlf), Self::U8),
174 tlf if <u16>::check_tlf(tlf) => map(<u16>::parse_with_tlf(input, tlf), Self::U16),
175 tlf if <u32>::check_tlf(tlf) => map(<u32>::parse_with_tlf(input, tlf), Self::U32),
176 tlf if <u64>::check_tlf(tlf) => map(<u64>::parse_with_tlf(input, tlf), Self::U64),
177 tlf if <ListType>::check_tlf(tlf) => {
178 map(<ListType>::parse_with_tlf(input, tlf), Self::List)
179 }
180 _ => Err(ParseError::TlfMismatch(core::any::type_name::<Self>())),
181 }
182 }
183}
184
185impl<'i> core::fmt::Debug for Value<'i> {
186 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
187 match self {
188 Self::Bool(arg0) => write!(f, "{:?}", arg0),
189 Self::Bytes(arg0) => write!(f, "{:?}", OctetStrFormatter(arg0)),
190 Self::I8(arg0) => write!(f, "{:?}", NumberFormatter(arg0)),
191 Self::I16(arg0) => write!(f, "{:?}", NumberFormatter(arg0)),
192 Self::I32(arg0) => write!(f, "{:?}", NumberFormatter(arg0)),
193 Self::I64(arg0) => write!(f, "{:?}", NumberFormatter(arg0)),
194 Self::U8(arg0) => write!(f, "{:?}", NumberFormatter(arg0)),
195 Self::U16(arg0) => write!(f, "{:?}", NumberFormatter(arg0)),
196 Self::U32(arg0) => write!(f, "{:?}", NumberFormatter(arg0)),
197 Self::U64(arg0) => write!(f, "{:?}", NumberFormatter(arg0)),
198 Self::List(arg0) => write!(f, "{:?}", arg0),
199 }
200 }
201}
202
203#[derive(Debug, PartialEq, Eq, Clone)]
204pub enum ListType {
206 Time(Time),
208}
209
210impl<'i> SmlParseTlf<'i> for ListType {
211 fn check_tlf(tlf: &TypeLengthField) -> bool {
212 tlf.ty == Ty::ListOf && tlf.len == 2
213 }
214
215 fn parse_with_tlf(input: &'i [u8], _tlf: &TypeLengthField) -> ResTy<'i, Self> {
216 let (input, tag) = u8::parse(input)?;
217 match tag {
218 1 => {
219 let (input, x) = <Time>::parse(input)?;
220 Ok((input, ListType::Time(x)))
221 }
222 _ => Err(ParseError::UnexpectedVariant),
223 }
224 }
225}
226
227#[derive(PartialEq, Eq, Clone)]
228pub enum Status {
230 Status8(u8),
232 Status16(u16),
234 Status32(u32),
236 Status64(u64),
238}
239
240impl<'i> SmlParseTlf<'i> for Status {
241 fn check_tlf(_tlf: &TypeLengthField) -> bool {
242 true
243 }
244
245 fn parse_with_tlf(input: &'i [u8], tlf: &TypeLengthField) -> ResTy<'i, Self> {
246 match tlf {
247 tlf if <u8>::check_tlf(tlf) => map(<u8>::parse_with_tlf(input, tlf), Self::Status8),
248 tlf if <u16>::check_tlf(tlf) => map(<u16>::parse_with_tlf(input, tlf), Self::Status16),
249 tlf if <u32>::check_tlf(tlf) => map(<u32>::parse_with_tlf(input, tlf), Self::Status32),
250 tlf if <u64>::check_tlf(tlf) => map(<u64>::parse_with_tlf(input, tlf), Self::Status64),
251 _ => Err(ParseError::TlfMismatch(core::any::type_name::<Self>())),
252 }
253 }
254}
255
256impl ::core::fmt::Debug for Status {
257 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
258 match self {
259 Self::Status8(x) => write!(f, "{:?}", NumberFormatter(x)),
260 Self::Status16(x) => write!(f, "{:?}", NumberFormatter(x)),
261 Self::Status32(x) => write!(f, "{:?}", NumberFormatter(x)),
262 Self::Status64(x) => write!(f, "{:?}", NumberFormatter(x)),
263 }
264 }
265}
266
267pub type Unit = u8; #[derive(PartialEq, Eq, Clone)]
271pub struct CloseResponse<'i> {
273 pub global_signature: Option<Signature<'i>>,
275}
276
277impl<'i> SmlParseTlf<'i> for CloseResponse<'i> {
278 fn check_tlf(tlf: &TypeLengthField) -> bool {
279 *tlf == TypeLengthField::new(Ty::ListOf, 1usize as u32)
280 }
281
282 fn parse_with_tlf(input: &'i [u8], _tlf: &TypeLengthField) -> ResTy<'i, Self> {
283 let (input, global_signature) = <Option<Signature<'i>>>::parse(input)?;
284 let val = CloseResponse { global_signature };
285 Ok((input, val))
286 }
287}
288
289impl<'i> core::fmt::Debug for CloseResponse<'i> {
290 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
291 let mut x = f.debug_struct("CloseResponse");
292 if let Some(e) = &self.global_signature {
293 x.field("global_signature", &e);
294 }
295 x.finish()
296 }
297}
298
299#[derive(Debug, PartialEq, Eq, Clone)]
300pub(crate) struct EndOfSmlMessage;
301
302impl<'i> SmlParse<'i> for EndOfSmlMessage {
303 fn parse(input: &'i [u8]) -> ResTy<Self> {
304 let (input, b) = take_byte(input)?;
305 if b != 0x00 {
306 return Err(ParseError::MsgEndMismatch);
307 }
308 Ok((input, EndOfSmlMessage))
309 }
310}
311
312#[derive(PartialEq, Eq, Clone)]
313pub enum Time {
315 SecIndex(u32),
317}
318
319impl<'i> SmlParseTlf<'i> for Time {
320 fn check_tlf(tlf: &TypeLengthField) -> bool {
321 (tlf.ty == Ty::ListOf && tlf.len == 2) || *tlf == TypeLengthField::new(Ty::Unsigned, 4)
322 }
323
324 fn parse_with_tlf(input: &'i [u8], tlf: &TypeLengthField) -> ResTy<'i, Self> {
325 if *tlf == TypeLengthField::new(Ty::Unsigned, 4) {
331 let (input, bytes) = take::<4>(input)?;
332 return Ok((input, Time::SecIndex(u32::from_be_bytes(*bytes))));
333 }
334
335 let (input, tag) = u8::parse(input)?;
336 match tag {
337 1 => {
338 let (input, x) = <u32>::parse(input)?;
339 Ok((input, Time::SecIndex(x)))
340 }
341 _ => Err(ParseError::UnexpectedVariant),
342 }
343 }
344}
345
346impl ::core::fmt::Debug for Time {
347 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
348 match self {
349 Self::SecIndex(arg0) => write!(f, "SecIndex({})", arg0),
350 }
351 }
352}
353
354pub type Signature<'i> = OctetStr<'i>;