1use jzon::JsonValue;
4
5use crate::{
6 de::Error,
7 error::*,
8 types::{fields::Fields, *},
9 Decode,
10};
11
12macro_rules! decode_jer_value {
13 ($decoder_fn:expr, $input:expr) => {
14 $input
15 .pop()
16 .ok_or_else(|| DecodeError::from(JerDecodeErrorKind::eoi()))
17 .and_then($decoder_fn)
18 };
19}
20
21pub struct Decoder {
22 stack: alloc::vec::Vec<JsonValue>,
23}
24
25impl Decoder {
26 pub fn new(input: &str) -> Result<Self, <Decoder as crate::de::Decoder>::Error> {
27 let root = jzon::parse(input).map_err(|e| {
28 DecodeError::parser_fail(
29 alloc::format!("Error parsing JER JSON {e:?}"),
30 crate::Codec::Jer,
31 )
32 })?;
33 Ok(Self {
34 stack: alloc::vec![root],
35 })
36 }
37}
38
39impl From<JsonValue> for Decoder {
40 fn from(value: JsonValue) -> Self {
41 Self {
42 stack: alloc::vec![value],
43 }
44 }
45}
46
47impl crate::Decoder for Decoder {
48 type Error = DecodeError;
49
50 fn decode_any(&mut self) -> Result<Any, Self::Error> {
51 decode_jer_value!(Self::any_from_value, self.stack)
52 }
53
54 fn decode_bit_string(
55 &mut self,
56 _t: crate::Tag,
57 constraints: Constraints,
58 ) -> Result<BitString, Self::Error> {
59 let (mut padded, bitstring_length) = if let Some(size) = constraints
60 .size()
61 .and_then(|s| s.constraint.is_fixed().then_some(s.constraint.as_start()))
62 .flatten()
63 {
64 let value = BitString::try_from_vec(decode_jer_value!(
65 Self::octet_string_from_value,
66 self.stack
67 )?)
68 .map_err(|e| {
69 DecodeError::custom(
70 alloc::format!("Failed to create BitString from bytes: {e:02x?}"),
71 self.codec(),
72 )
73 })?;
74 (value, *size)
75 } else {
76 let last = self.stack.pop().ok_or_else(JerDecodeErrorKind::eoi)?;
77 let value_map = last
78 .as_object()
79 .ok_or_else(|| JerDecodeErrorKind::TypeMismatch {
80 needed: "object",
81 found: "unknown".into(),
82 })?;
83 let (value, length) = value_map
84 .get("value")
85 .and_then(|v| v.as_str())
86 .zip(value_map.get("length").and_then(|l| l.as_usize()))
87 .ok_or_else(|| JerDecodeErrorKind::TypeMismatch {
88 needed: "JSON object containing 'value' and 'length' properties.",
89 found: alloc::format!("{value_map:#?}"),
90 })?;
91 (
92 (0..value.len())
93 .step_by(2)
94 .map(|i| u8::from_str_radix(&value[i..=i + 1], 16))
95 .collect::<Result<BitString, _>>()
96 .map_err(|e| JerDecodeErrorKind::InvalidJerBitstring { parse_int_err: e })?,
97 length,
98 )
99 };
100 let padding_length = if bitstring_length % 8 == 0 {
101 0
102 } else {
103 8 - (bitstring_length % 8)
104 };
105 for _ in 0..padding_length {
106 padded.pop();
107 }
108 Ok(padded)
109 }
110
111 fn decode_bool(&mut self, _t: crate::Tag) -> Result<bool, Self::Error> {
112 decode_jer_value!(Self::boolean_from_value, self.stack)
113 }
114
115 fn decode_enumerated<E: Enumerated>(&mut self, _t: crate::Tag) -> Result<E, Self::Error> {
116 decode_jer_value!(Self::enumerated_from_value, self.stack)
117 }
118
119 fn decode_integer<I: crate::types::IntegerType>(
120 &mut self,
121 _t: crate::Tag,
122 _c: Constraints,
123 ) -> Result<I, Self::Error> {
124 decode_jer_value!(Self::integer_from_value::<I>, self.stack)
125 }
126
127 fn decode_null(&mut self, _t: crate::Tag) -> Result<(), Self::Error> {
128 decode_jer_value!(Self::null_from_value, self.stack)
129 }
130
131 fn decode_object_identifier(
132 &mut self,
133 _t: crate::Tag,
134 ) -> Result<ObjectIdentifier, Self::Error> {
135 decode_jer_value!(Self::object_identifier_from_value, self.stack)
136 }
137
138 fn decode_sequence<D, DF, F>(
139 &mut self,
140 _: crate::Tag,
141 _: Option<DF>,
142 decode_fn: F,
143 ) -> Result<D, Self::Error>
144 where
145 D: Constructed,
146 F: FnOnce(&mut Self) -> Result<D, Self::Error>,
147 {
148 let mut last = self.stack.pop().ok_or_else(JerDecodeErrorKind::eoi)?;
149 let value_map = last
150 .as_object_mut()
151 .ok_or_else(|| JerDecodeErrorKind::TypeMismatch {
152 needed: "object",
153 found: "unknown".into(),
154 })?;
155 let mut field_names = [D::FIELDS, D::EXTENDED_FIELDS.unwrap_or(Fields::empty())]
156 .iter()
157 .flat_map(|f| f.iter())
158 .map(|f| f.name)
159 .collect::<alloc::vec::Vec<&str>>();
160 field_names.reverse();
161 for name in field_names {
162 self.stack
163 .push(value_map.remove(name).unwrap_or(JsonValue::Null));
164 }
165
166 (decode_fn)(self)
167 }
168
169 fn decode_sequence_of<D: crate::Decode>(
170 &mut self,
171 _t: crate::Tag,
172 _c: Constraints,
173 ) -> Result<SequenceOf<D>, Self::Error> {
174 decode_jer_value!(|v| self.sequence_of_from_value(v), self.stack)
175 }
176
177 fn decode_set_of<D: crate::Decode + Ord>(
178 &mut self,
179 _t: crate::Tag,
180 _c: Constraints,
181 ) -> Result<SetOf<D>, Self::Error> {
182 decode_jer_value!(|v| self.set_of_from_value(v), self.stack)
183 }
184
185 fn decode_octet_string(
186 &mut self,
187 _t: crate::Tag,
188 _c: Constraints,
189 ) -> Result<alloc::vec::Vec<u8>, Self::Error> {
190 decode_jer_value!(Self::octet_string_from_value, self.stack)
191 }
192
193 fn decode_utf8_string(
194 &mut self,
195 _t: crate::Tag,
196 _c: Constraints,
197 ) -> Result<Utf8String, Self::Error> {
198 decode_jer_value!(Self::string_from_value, self.stack)
199 }
200
201 fn decode_visible_string(
202 &mut self,
203 _t: crate::Tag,
204 _c: Constraints,
205 ) -> Result<VisibleString, Self::Error> {
206 decode_jer_value!(Self::string_from_value, self.stack)?
207 .try_into()
208 .map_err(|e| {
209 DecodeError::string_conversion_failed(
210 Tag::VISIBLE_STRING,
211 alloc::format!("Error transforming VisibleString: {e:?}"),
212 crate::Codec::Jer,
213 )
214 })
215 }
216
217 fn decode_general_string(
218 &mut self,
219 _t: crate::Tag,
220 _c: Constraints,
221 ) -> Result<GeneralString, Self::Error> {
222 decode_jer_value!(Self::string_from_value, self.stack)?
223 .try_into()
224 .map_err(|e| {
225 DecodeError::string_conversion_failed(
226 Tag::GENERAL_STRING,
227 alloc::format!("Error transforming GeneralString: {e:?}"),
228 crate::Codec::Jer,
229 )
230 })
231 }
232
233 fn decode_ia5_string(
234 &mut self,
235 _t: crate::Tag,
236 _c: Constraints,
237 ) -> Result<Ia5String, Self::Error> {
238 decode_jer_value!(Self::string_from_value, self.stack)?
239 .try_into()
240 .map_err(|e| {
241 DecodeError::string_conversion_failed(
242 Tag::IA5_STRING,
243 alloc::format!("Error transforming IA5String: {e:?}"),
244 crate::Codec::Jer,
245 )
246 })
247 }
248
249 fn decode_printable_string(
250 &mut self,
251 _t: crate::Tag,
252 _c: Constraints,
253 ) -> Result<PrintableString, Self::Error> {
254 decode_jer_value!(Self::string_from_value, self.stack)?
255 .try_into()
256 .map_err(|e| {
257 DecodeError::string_conversion_failed(
258 Tag::PRINTABLE_STRING,
259 alloc::format!("Error transforming PrintableString: {e:?}"),
260 crate::Codec::Jer,
261 )
262 })
263 }
264
265 fn decode_numeric_string(
266 &mut self,
267 _t: crate::Tag,
268 _c: Constraints,
269 ) -> Result<NumericString, Self::Error> {
270 decode_jer_value!(Self::string_from_value, self.stack)?
271 .try_into()
272 .map_err(|e| {
273 DecodeError::string_conversion_failed(
274 Tag::NUMERIC_STRING,
275 alloc::format!("Error transforming NumericString: {e:?}"),
276 crate::Codec::Jer,
277 )
278 })
279 }
280
281 fn decode_teletex_string(
282 &mut self,
283 _t: crate::Tag,
284 _c: Constraints,
285 ) -> Result<TeletexString, Self::Error> {
286 todo!()
287 }
288
289 fn decode_bmp_string(
290 &mut self,
291 _t: crate::Tag,
292 _c: Constraints,
293 ) -> Result<BmpString, Self::Error> {
294 decode_jer_value!(Self::string_from_value, self.stack)?
295 .try_into()
296 .map_err(|e| {
297 DecodeError::string_conversion_failed(
298 Tag::BMP_STRING,
299 alloc::format!("Error transforming BMPString: {e:?}"),
300 crate::Codec::Jer,
301 )
302 })
303 }
304
305 fn decode_explicit_prefix<D: crate::Decode>(
306 &mut self,
307 _t: crate::Tag,
308 ) -> Result<D, Self::Error> {
309 D::decode(self)
310 }
311
312 fn decode_utc_time(&mut self, _t: crate::Tag) -> Result<UtcTime, Self::Error> {
313 decode_jer_value!(Self::utc_time_from_value, self.stack)
314 }
315
316 fn decode_generalized_time(&mut self, _t: crate::Tag) -> Result<GeneralizedTime, Self::Error> {
317 decode_jer_value!(Self::general_time_from_value, self.stack)
318 }
319
320 fn decode_set<FIELDS, SET, D, F>(
321 &mut self,
322 _t: crate::Tag,
323 decode_fn: D,
324 field_fn: F,
325 ) -> Result<SET, Self::Error>
326 where
327 SET: crate::Decode + Constructed,
328 FIELDS: crate::Decode,
329 D: Fn(&mut Self, usize, crate::Tag) -> Result<FIELDS, Self::Error>,
330 F: FnOnce(alloc::vec::Vec<FIELDS>) -> Result<SET, Self::Error>,
331 {
332 let mut last = self.stack.pop().ok_or_else(JerDecodeErrorKind::eoi)?;
333 let value_map = last
334 .as_object_mut()
335 .ok_or_else(|| JerDecodeErrorKind::TypeMismatch {
336 needed: "object",
337 found: "unknown".into(),
338 })?;
339 let mut field_indices = SET::FIELDS
340 .iter()
341 .enumerate()
342 .collect::<alloc::vec::Vec<_>>();
343 let mut fields = alloc::vec![];
344 field_indices
345 .sort_by(|(_, a), (_, b)| a.tag_tree.smallest_tag().cmp(&b.tag_tree.smallest_tag()));
346 for (index, field) in field_indices.into_iter() {
347 self.stack
348 .push(value_map.remove(field.name).unwrap_or(JsonValue::Null));
349 fields.push((decode_fn)(self, index, field.tag)?);
350 }
351
352 for (index, field) in SET::EXTENDED_FIELDS
353 .iter()
354 .flat_map(|fields| fields.iter())
355 .enumerate()
356 {
357 self.stack
358 .push(value_map.remove(field.name).unwrap_or(JsonValue::Null));
359 fields.push((decode_fn)(self, index + SET::FIELDS.len(), field.tag)?)
360 }
361
362 (field_fn)(fields)
363 }
364
365 fn decode_choice<D>(&mut self, _c: Constraints) -> Result<D, Self::Error>
366 where
367 D: DecodeChoice,
368 {
369 decode_jer_value!(|v| self.choice_from_value::<D>(v), self.stack)
370 }
371
372 fn decode_optional<D: crate::Decode>(&mut self) -> Result<Option<D>, Self::Error> {
373 let last = self.stack.pop().ok_or_else(JerDecodeErrorKind::eoi)?;
374 match last {
375 JsonValue::Null => Ok(None),
376 v => {
377 self.stack.push(v);
378 Some(D::decode(self)).transpose()
379 }
380 }
381 }
382
383 fn decode_optional_with_tag<D: crate::Decode>(
384 &mut self,
385 _: crate::Tag,
386 ) -> Result<Option<D>, Self::Error> {
387 self.decode_optional()
388 }
389
390 fn decode_optional_with_constraints<D: crate::Decode>(
391 &mut self,
392 _: Constraints,
393 ) -> Result<Option<D>, Self::Error> {
394 self.decode_optional()
395 }
396
397 fn decode_optional_with_tag_and_constraints<D: crate::Decode>(
398 &mut self,
399 _t: crate::Tag,
400 _c: Constraints,
401 ) -> Result<Option<D>, Self::Error> {
402 self.decode_optional()
403 }
404
405 fn decode_extension_addition_with_constraints<D>(
406 &mut self,
407 _: Constraints,
408 ) -> Result<Option<D>, Self::Error>
409 where
410 D: crate::Decode,
411 {
412 self.decode_optional()
413 }
414
415 fn decode_extension_addition_group<D: crate::Decode + Constructed>(
416 &mut self,
417 ) -> Result<Option<D>, Self::Error> {
418 self.decode_optional()
419 }
420
421 fn codec(&self) -> crate::Codec {
422 crate::Codec::Jer
423 }
424}
425
426impl Decoder {
433 fn any_from_value(value: JsonValue) -> Result<Any, <Self as crate::de::Decoder>::Error> {
434 Ok(Any::new(alloc::format!("{value}").as_bytes().to_vec()))
435 }
436
437 fn boolean_from_value(value: JsonValue) -> Result<bool, DecodeError> {
438 Ok(value
439 .as_bool()
440 .ok_or_else(|| JerDecodeErrorKind::TypeMismatch {
441 needed: "boolean",
442 found: alloc::format!("{value}"),
443 })?)
444 }
445
446 fn enumerated_from_value<E: Enumerated>(value: JsonValue) -> Result<E, DecodeError> {
447 let identifier = value
448 .as_str()
449 .ok_or_else(|| JerDecodeErrorKind::TypeMismatch {
450 needed: "enumerated item as string",
451 found: alloc::format!("{value}"),
452 })?;
453 Ok(E::from_identifier(identifier).ok_or_else(|| {
454 JerDecodeErrorKind::InvalidEnumDiscriminant {
455 discriminant: alloc::string::String::from(identifier),
456 }
457 })?)
458 }
459
460 fn integer_from_value<I: crate::types::IntegerType>(
461 value: JsonValue,
462 ) -> Result<I, DecodeError> {
463 value
464 .as_i64()
465 .ok_or_else(|| JerDecodeErrorKind::TypeMismatch {
466 needed: "number (supported range -2^63..2^63)",
467 found: alloc::format!("{value}"),
468 })?
469 .try_into()
470 .map_err(|_| DecodeError::integer_overflow(I::WIDTH, crate::Codec::Jer))
471 }
472
473 fn null_from_value(value: JsonValue) -> Result<(), DecodeError> {
474 Ok(value
475 .is_null()
476 .then_some(())
477 .ok_or_else(|| JerDecodeErrorKind::TypeMismatch {
478 needed: "null",
479 found: alloc::format!("{value}"),
480 })?)
481 }
482
483 fn object_identifier_from_value(value: JsonValue) -> Result<ObjectIdentifier, DecodeError> {
484 #[allow(clippy::unnecessary_lazy_evaluations)]
486 Ok(value
487 .as_str()
488 .ok_or_else(|| JerDecodeErrorKind::TypeMismatch {
489 needed: "number array",
490 found: alloc::format!("{value}"),
491 })?
492 .split('.')
493 .map(|arc| {
494 arc.parse::<u32>()
495 .map_err(|_| JerDecodeErrorKind::TypeMismatch {
496 needed: "OID arc number",
497 found: arc.into(),
498 })
499 })
500 .collect::<Result<alloc::vec::Vec<u32>, _>>()
501 .ok()
502 .and_then(|arcs| Oid::new(&arcs).map(ObjectIdentifier::from))
503 .ok_or_else(|| JerDecodeErrorKind::InvalidOIDString { value })?)
504 }
505
506 fn sequence_of_from_value<D: Decode>(
507 &mut self,
508 value: JsonValue,
509 ) -> Result<SequenceOf<D>, DecodeError> {
510 value
511 .as_array()
512 .ok_or_else(|| JerDecodeErrorKind::TypeMismatch {
513 needed: "array",
514 found: alloc::format!("{value}"),
515 })?
516 .clone()
517 .into_iter()
518 .map(|v| {
519 self.stack.push(v);
520 D::decode(self)
521 })
522 .collect()
523 }
524
525 fn set_of_from_value<D: Decode + Ord>(
526 &mut self,
527 value: JsonValue,
528 ) -> Result<SetOf<D>, DecodeError> {
529 value
530 .as_array()
531 .ok_or_else(|| JerDecodeErrorKind::TypeMismatch {
532 needed: "array",
533 found: alloc::format!("{value}"),
534 })?
535 .clone()
536 .into_iter()
537 .try_fold(SetOf::new(), |mut acc, v| {
538 self.stack.push(v);
539 acc.insert(D::decode(self)?);
540 Ok(acc)
541 })
542 }
543
544 fn string_from_value(value: JsonValue) -> Result<alloc::string::String, DecodeError> {
545 Ok(value
546 .as_str()
547 .ok_or_else(|| JerDecodeErrorKind::TypeMismatch {
548 needed: "string",
549 found: alloc::format!("{value}"),
550 })
551 .map(|n| n.into())?)
552 }
553
554 fn choice_from_value<D>(&mut self, value: JsonValue) -> Result<D, DecodeError>
555 where
556 D: DecodeChoice,
557 {
558 let tag = value
559 .as_object()
560 .ok_or_else(|| JerDecodeErrorKind::TypeMismatch {
561 needed: "object",
562 found: alloc::format!("{value}"),
563 })?
564 .iter()
565 .next()
566 .and_then(|(k, v)| {
567 D::IDENTIFIERS
568 .iter()
569 .enumerate()
570 .find(|id| id.1.eq_ignore_ascii_case(k))
571 .map(|(i, _)| (i, v))
572 })
573 .map_or(Tag::EOC, |(i, v)| {
574 match variants::Variants::from_slice(
575 &[D::VARIANTS, D::EXTENDED_VARIANTS.unwrap_or(&[])].concat(),
576 )
577 .get(i)
578 {
579 Some(t) => {
580 self.stack.push(v.clone());
581 *t
582 }
583 None => Tag::EOC,
584 }
585 });
586 D::from_tag(self, tag)
587 }
588
589 fn octet_string_from_value(value: JsonValue) -> Result<alloc::vec::Vec<u8>, DecodeError> {
590 let octet_string = value
591 .as_str()
592 .ok_or_else(|| JerDecodeErrorKind::TypeMismatch {
593 needed: "hex string",
594 found: alloc::format!("{value}"),
595 })?;
596 Ok((0..octet_string.len())
597 .step_by(2)
598 .map(|i| u8::from_str_radix(&octet_string[i..=i + 1], 16))
599 .collect::<Result<alloc::vec::Vec<u8>, _>>()
600 .map_err(|_| JerDecodeErrorKind::InvalidJerOctetString {})?)
601 }
602
603 fn utc_time_from_value(value: JsonValue) -> Result<chrono::DateTime<chrono::Utc>, DecodeError> {
604 crate::ber::de::Decoder::parse_any_utc_time_string(
605 value
606 .as_str()
607 .ok_or_else(|| JerDecodeErrorKind::TypeMismatch {
608 needed: "time string",
609 found: alloc::format!("{value}"),
610 })?
611 .into(),
612 )
613 }
614
615 fn general_time_from_value(
616 value: JsonValue,
617 ) -> Result<chrono::DateTime<chrono::FixedOffset>, DecodeError> {
618 crate::ber::de::Decoder::parse_any_generalized_time_string(
619 value
620 .as_str()
621 .ok_or_else(|| JerDecodeErrorKind::TypeMismatch {
622 needed: "time string",
623 found: alloc::format!("{value}"),
624 })?
625 .into(),
626 )
627 }
628}