1use core::num::ParseIntError;
4
5use super::strings::PermittedAlphabetError;
6use alloc::{boxed::Box, string::ToString};
7
8use snafu::Snafu;
9#[cfg(feature = "backtraces")]
10use snafu::{Backtrace, GenerateImplicitData};
11
12use crate::Codec;
13use crate::de::Error;
14use crate::types::{Tag, constraints::Bounded, variants::Variants};
15use num_bigint::BigInt;
16
17#[derive(Debug)]
19#[non_exhaustive]
20#[allow(missing_docs)]
21pub enum CodecDecodeError {
22 Ber(BerDecodeErrorKind),
23 Cer(CerDecodeErrorKind),
24 Der(DerDecodeErrorKind),
25 Uper(UperDecodeErrorKind),
26 Aper(AperDecodeErrorKind),
27 Jer(JerDecodeErrorKind),
28 Oer(OerDecodeErrorKind),
29 Coer(CoerDecodeErrorKind),
30 Xer(XerDecodeErrorKind),
31}
32
33impl core::fmt::Display for CodecDecodeError {
34 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
35 match self {
36 CodecDecodeError::Ber(kind) => write!(f, "BER decoding error: {kind}"),
37 CodecDecodeError::Cer(kind) => write!(f, "CER decoding error: {kind}"),
38 CodecDecodeError::Der(kind) => write!(f, "DER decoding error: {kind}"),
39 CodecDecodeError::Uper(kind) => write!(f, "UPER decoding error: {kind}"),
40 CodecDecodeError::Aper(kind) => write!(f, "APER decoding error: {kind}"),
41 CodecDecodeError::Jer(kind) => write!(f, "JER decoding error: {kind}"),
42 CodecDecodeError::Oer(kind) => write!(f, "OER decoding error: {kind}"),
43 CodecDecodeError::Coer(kind) => write!(f, "COER decoding error: {kind}"),
44 CodecDecodeError::Xer(kind) => write!(f, "XER decoding error: {kind}"),
45 }
46 }
47}
48
49macro_rules! impl_from {
50 ($variant:ident, $error_kind:ty) => {
51 impl From<$error_kind> for DecodeError {
52 fn from(error: $error_kind) -> Self {
53 Self::from_codec_kind(CodecDecodeError::$variant(error))
54 }
55 }
56 };
57}
58
59impl_from!(Ber, BerDecodeErrorKind);
61impl_from!(Cer, CerDecodeErrorKind);
62impl_from!(Der, DerDecodeErrorKind);
63impl_from!(Uper, UperDecodeErrorKind);
64impl_from!(Aper, AperDecodeErrorKind);
65impl_from!(Jer, JerDecodeErrorKind);
66impl_from!(Oer, OerDecodeErrorKind);
67impl_from!(Coer, CoerDecodeErrorKind);
68impl_from!(Xer, XerDecodeErrorKind);
69
70impl From<CodecDecodeError> for DecodeError {
71 fn from(error: CodecDecodeError) -> Self {
72 Self::from_codec_kind(error)
73 }
74}
75
76#[derive(Debug)]
153#[allow(clippy::module_name_repetitions)]
154pub struct DecodeError {
155 pub kind: Box<DecodeErrorKind>,
157 pub codec: Codec,
159 #[cfg(feature = "backtraces")]
161 pub backtrace: Backtrace,
162}
163
164impl core::fmt::Display for DecodeError {
165 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
166 write!(f, "{} (Codec: {})", self.kind, self.codec)?;
167 #[cfg(feature = "backtraces")]
168 write!(f, "\n\nBacktrace:\n{}", self.backtrace)?;
169 Ok(())
170 }
171}
172
173impl DecodeError {
174 fn eof(codec: Codec) -> Self {
176 Self::from_kind(DecodeErrorKind::Eof, codec)
177 }
178
179 #[must_use]
181 pub fn permitted_alphabet_error(reason: PermittedAlphabetError, codec: Codec) -> Self {
182 Self::from_kind(DecodeErrorKind::PermittedAlphabetError { reason }, codec)
183 }
184
185 #[must_use]
187 pub fn size_constraint_not_satisfied(
188 size: Option<usize>,
189 expected: alloc::string::String,
190 codec: Codec,
191 ) -> Self {
192 Self::from_kind(
193 DecodeErrorKind::SizeConstraintNotSatisfied { size, expected },
194 codec,
195 )
196 }
197
198 #[must_use]
200 pub fn value_constraint_not_satisfied(
201 value: BigInt,
202 expected: Bounded<i128>,
203 codec: Codec,
204 ) -> Self {
205 Self::from_kind(
206 DecodeErrorKind::ValueConstraintNotSatisfied { value, expected },
207 codec,
208 )
209 }
210 #[must_use]
213 pub fn inner_subtype_constraint_not_satisfied(
214 reason: super::InnerSubtypeConstraintError,
215 codec: Codec,
216 ) -> Self {
217 Self::from_kind(
218 DecodeErrorKind::InnerSubtypeConstraintNotSatisfied { reason },
219 codec,
220 )
221 }
222
223 #[must_use]
225 pub fn discriminant_value_not_found(discriminant: isize, codec: Codec) -> Self {
226 Self::from_kind(
227 DecodeErrorKind::DiscriminantValueNotFound { discriminant },
228 codec,
229 )
230 }
231
232 #[must_use]
234 pub fn range_exceeds_platform_width(needed: u32, present: u32, codec: Codec) -> Self {
235 Self::from_kind(
236 DecodeErrorKind::RangeExceedsPlatformWidth { needed, present },
237 codec,
238 )
239 }
240
241 #[must_use]
243 pub fn fixed_string_conversion_failed(
244 tag: Tag,
245 actual: usize,
246 expected: usize,
247 codec: Codec,
248 ) -> Self {
249 Self::from_kind(
250 DecodeErrorKind::FixedStringConversionFailed {
251 tag,
252 actual,
253 expected,
254 },
255 codec,
256 )
257 }
258
259 #[must_use]
261 pub fn incorrect_item_number_in_sequence(expected: usize, actual: usize, codec: Codec) -> Self {
262 Self::from_kind(
263 DecodeErrorKind::IncorrectItemNumberInSequence { expected, actual },
264 codec,
265 )
266 }
267
268 #[must_use]
270 pub fn integer_overflow(max_width: u32, codec: Codec) -> Self {
271 Self::from_kind(DecodeErrorKind::IntegerOverflow { max_width }, codec)
272 }
273
274 #[must_use]
276 pub fn integer_type_conversion_failed(msg: alloc::string::String, codec: Codec) -> Self {
277 Self::from_kind(DecodeErrorKind::IntegerTypeConversionFailed { msg }, codec)
278 }
279
280 #[must_use]
282 pub fn invalid_bit_string(bits: u8, codec: Codec) -> Self {
283 Self::from_kind(DecodeErrorKind::InvalidBitString { bits }, codec)
284 }
285
286 #[must_use]
288 pub fn missing_tag_class_or_value_in_sequence_or_set(
289 class: crate::types::Class,
290 value: u32,
291 codec: Codec,
292 ) -> Self {
293 Self::from_kind(
294 DecodeErrorKind::MissingTagClassOrValueInSequenceOrSet { class, value },
295 codec,
296 )
297 }
298
299 #[must_use]
301 pub fn type_not_extensible(codec: Codec) -> Self {
302 Self::from_kind(DecodeErrorKind::TypeNotExtensible, codec)
303 }
304
305 #[must_use]
307 pub fn parser_fail(msg: alloc::string::String, codec: Codec) -> Self {
308 DecodeError::from_kind(DecodeErrorKind::Parser { msg }, codec)
309 }
310
311 #[must_use]
313 pub fn real_not_supported(codec: Codec) -> Self {
314 DecodeError::from_kind(DecodeErrorKind::RealNotSupported, codec)
315 }
316
317 #[must_use]
319 pub fn required_extension_not_present(tag: Tag, codec: Codec) -> Self {
320 Self::from_kind(DecodeErrorKind::RequiredExtensionNotPresent { tag }, codec)
321 }
322
323 #[must_use]
325 pub fn enumeration_index_not_found(index: usize, extended_list: bool, codec: Codec) -> Self {
326 Self::from_kind(
327 DecodeErrorKind::EnumerationIndexNotFound {
328 index,
329 extended_list,
330 },
331 codec,
332 )
333 }
334
335 #[must_use]
337 pub fn choice_index_exceeds_platform_width(
338 needed: u32,
339 present: DecodeError,
340 codec: Codec,
341 ) -> Self {
342 Self::from_kind(
343 DecodeErrorKind::ChoiceIndexExceedsPlatformWidth { needed, present },
344 codec,
345 )
346 }
347
348 #[must_use]
350 pub fn length_exceeds_platform_width(msg: alloc::string::String, codec: Codec) -> Self {
351 Self::from_kind(DecodeErrorKind::LengthExceedsPlatformWidth { msg }, codec)
352 }
353
354 #[must_use]
356 pub fn choice_index_not_found(index: usize, variants: Variants, codec: Codec) -> Self {
357 Self::from_kind(
358 DecodeErrorKind::ChoiceIndexNotFound { index, variants },
359 codec,
360 )
361 }
362
363 #[must_use]
365 pub fn string_conversion_failed(tag: Tag, msg: alloc::string::String, codec: Codec) -> Self {
366 Self::from_kind(DecodeErrorKind::StringConversionFailed { tag, msg }, codec)
367 }
368
369 #[must_use]
371 pub fn unexpected_extra_data(length: usize, codec: Codec) -> Self {
372 Self::from_kind(DecodeErrorKind::UnexpectedExtraData { length }, codec)
373 }
374
375 #[must_use]
377 pub fn unexpected_empty_input(codec: Codec) -> Self {
378 Self::from_kind(DecodeErrorKind::UnexpectedEmptyInput, codec)
379 }
380
381 pub fn assert_length(
383 expected: usize,
384 actual: usize,
385 codec: Codec,
386 ) -> core::result::Result<(), DecodeError> {
387 if expected == actual {
388 Ok(())
389 } else {
390 Err(DecodeError::from_kind(
391 DecodeErrorKind::MismatchedLength { expected, actual },
392 codec,
393 ))
394 }
395 }
396
397 pub(crate) fn map_nom_err<T: core::fmt::Debug>(
398 error: nom::Err<nom::error::Error<T>>,
399 codec: Codec,
400 ) -> DecodeError {
401 match error {
402 nom::Err::Incomplete(needed) => DecodeError::incomplete(needed, codec),
403 nom::Err::Failure(e) | nom::Err::Error(e) => {
404 if e.code == nom::error::ErrorKind::Eof {
405 DecodeError::eof(codec)
406 } else {
407 DecodeError::parser_fail(alloc::format!("Parsing Failure: {e:?}"), codec)
408 }
409 }
410 }
411 }
412
413 #[must_use]
415 pub fn from_kind(kind: DecodeErrorKind, codec: Codec) -> Self {
416 Self {
417 kind: Box::new(kind),
418 codec,
419 #[cfg(feature = "backtraces")]
420 backtrace: Backtrace::generate(),
421 }
422 }
423
424 #[must_use]
425 fn from_codec_kind(inner: CodecDecodeError) -> Self {
426 let codec = match inner {
427 CodecDecodeError::Ber(_) => crate::Codec::Ber,
428 #[allow(unreachable_patterns)]
429 CodecDecodeError::Cer(_) => crate::Codec::Cer,
430 CodecDecodeError::Der(_) => crate::Codec::Der,
431 #[allow(unreachable_patterns)]
432 CodecDecodeError::Uper(_) => crate::Codec::Uper,
433 #[allow(unreachable_patterns)]
434 CodecDecodeError::Aper(_) => crate::Codec::Aper,
435 CodecDecodeError::Jer(_) => crate::Codec::Jer,
436 CodecDecodeError::Oer(_) => crate::Codec::Oer,
437 CodecDecodeError::Coer(_) => crate::Codec::Coer,
438 CodecDecodeError::Xer(_) => crate::Codec::Xer,
439 };
440 Self {
441 kind: Box::new(DecodeErrorKind::CodecSpecific { inner }),
442 codec,
443 #[cfg(feature = "backtraces")]
444 backtrace: Backtrace::generate(),
445 }
446 }
447
448 #[must_use]
450 pub fn matches_root_cause<F>(&self, predicate: F) -> bool
451 where
452 F: Fn(&DecodeErrorKind) -> bool,
453 {
454 let mut root = self;
455 while let DecodeErrorKind::FieldError { nested, .. } = &*root.kind {
456 root = &**nested;
457 }
458
459 predicate(&root.kind)
460 }
461}
462
463impl core::error::Error for DecodeError {}
464
465#[derive(Snafu)]
467#[snafu(visibility(pub))]
468#[derive(Debug)]
469#[non_exhaustive]
470pub enum DecodeErrorKind {
471 #[snafu(display("Alphabet constraint not satisfied {}", reason))]
473 PermittedAlphabetError {
474 reason: PermittedAlphabetError,
476 },
477
478 #[snafu(display("Size constraint not satisfied: expected: {expected}; actual: {size:?}"))]
480 SizeConstraintNotSatisfied {
481 size: Option<usize>,
483 expected: alloc::string::String,
485 },
486
487 #[snafu(display("Value constraint not satisfied: expected: {expected}; actual: {value}"))]
489 ValueConstraintNotSatisfied {
490 value: BigInt,
492 expected: Bounded<i128>,
494 },
495 #[snafu(display("Inner subtype constraint not satisfied: {reason}"))]
497 InnerSubtypeConstraintNotSatisfied {
498 reason: super::InnerSubtypeConstraintError,
500 },
501
502 #[snafu(display("{inner}"))]
504 CodecSpecific {
505 inner: CodecDecodeError,
507 },
508
509 #[snafu(display(
511 "Enumeration index {} did not match any variant. Extended list checked: {}",
512 index,
513 extended_list
514 ))]
515 EnumerationIndexNotFound {
516 index: usize,
518 extended_list: bool,
520 },
521
522 #[snafu(display("Choice index {index} did not match any variant"))]
524 ChoiceIndexNotFound {
525 index: usize,
527 variants: Variants,
529 },
530
531 #[snafu(display(
533 "Choice index exceeds platform index width. Needed {needed} bytes, present: {present}"
534 ))]
535 ChoiceIndexExceedsPlatformWidth {
536 needed: u32,
538 present: DecodeError,
540 },
541
542 #[snafu(display("Custom error: {}", msg))]
544 Custom {
545 msg: alloc::string::String,
547 },
548
549 #[snafu(display("Discriminant value {} did not match any variant", discriminant))]
551 DiscriminantValueNotFound {
552 discriminant: isize,
554 },
555
556 #[snafu(display("Duplicate field for `{}`", name))]
558 DuplicateField {
559 name: &'static str,
561 },
562
563 #[snafu(display("Expected maximum of {} items", length))]
565 ExceedsMaxLength {
566 length: num_bigint::BigUint,
568 },
569
570 #[snafu(display("Length of the data exceeds platform address width"))]
572 LengthExceedsPlatformWidth {
573 msg: alloc::string::String,
575 },
576
577 #[snafu(display("Error when decoding field `{}`: {}", name, nested))]
579 FieldError {
580 name: &'static str,
582 nested: Box<DecodeError>,
584 },
585
586 #[snafu(display("Need more data to continue: {:?}", needed))]
590 Incomplete {
591 needed: nom::Needed,
593 },
594 #[snafu(display("Unexpected EOF when decoding"))]
597 Eof,
598
599 #[snafu(display(
601 "Invalid item number in Sequence: expected: {}; actual: {}",
602 expected,
603 actual
604 ))]
605 IncorrectItemNumberInSequence {
606 expected: usize,
608 actual: usize,
610 },
611
612 #[snafu(display("Actual integer larger than expected {} bits", max_width))]
614 IntegerOverflow {
615 max_width: u32,
617 },
618
619 #[snafu(display("Failed to cast integer to another integer type: {msg} "))]
621 IntegerTypeConversionFailed {
622 msg: alloc::string::String,
624 },
625
626 #[snafu(display("Invalid real encoding"))]
628 InvalidRealEncoding,
629
630 #[snafu(display("Decoder doesn't support `REAL` type"))]
632 RealNotSupported,
633
634 #[snafu(display("BitString contains an invalid amount of unused bits: {}", bits))]
636 InvalidBitString {
637 bits: u8,
639 },
640
641 #[snafu(display(
643 "Bool value is not `0` or `0xFF` as canonical requires. Actual: {}",
644 value
645 ))]
646 InvalidBool {
647 value: u8,
649 },
650
651 #[snafu(display("Length of Length cannot be zero"))]
653 ZeroLengthOfLength,
654 #[snafu(display("Expected {} bytes, actual length was {} bytes", expected, actual))]
656 MismatchedLength {
657 expected: usize,
659 actual: usize,
661 },
662
663 #[snafu(display("Missing field `{}`", name))]
665 MissingField {
666 name: &'static str,
668 },
669 #[snafu(display(
671 "Expected class: {}, value: {} in sequence or set Missing tag class or value in sequence or set",
672 class,
673 value
674 ))]
675 MissingTagClassOrValueInSequenceOrSet {
676 class: crate::types::Class,
678 value: u32,
680 },
681
682 #[snafu(display(
684 "Integer range larger than possible to address on this platform. needed: {needed} present: {present}"
685 ))]
686 RangeExceedsPlatformWidth {
687 needed: u32,
689 present: u32,
691 },
692 #[snafu(display("Extension with class `{}` and tag `{}` required, but not present", tag.class, tag.value))]
694 RequiredExtensionNotPresent {
695 tag: crate::types::Tag,
697 },
698 #[snafu(display("Error in Parser: {}", msg))]
700 Parser {
701 msg: alloc::string::String,
703 },
704 #[snafu(display(
706 "Failed to convert byte array into valid ASN.1 string. String type as tag: {} Error: {}",
707 tag,
708 msg
709 ))]
710 StringConversionFailed {
711 tag: Tag,
713 msg: alloc::string::String,
715 },
716 #[snafu(display(
718 "Failed to convert byte array into valid fixed-sized ASN.1 string. String type as tag: {}, actual: {}, expected: {}",
719 tag,
720 actual,
721 expected
722 ))]
723 FixedStringConversionFailed {
724 tag: Tag,
726 expected: usize,
728 actual: usize,
730 },
731 #[snafu(display("No valid choice for `{}`", name))]
733 NoValidChoice {
734 name: &'static str,
736 },
737
738 #[snafu(display("Attempted to decode extension on non-extensible type"))]
740 TypeNotExtensible,
741 #[snafu(display("Unexpected extra data found: length `{}` bytes", length))]
743 UnexpectedExtraData {
744 length: usize,
746 },
747 #[snafu(display("Unknown field with index {} and tag {}", index, tag))]
749 UnknownField {
750 index: usize,
752 tag: Tag,
754 },
755 #[snafu(display("No input was provided where expected in the given SEQUENCE or INTEGER type"))]
757 UnexpectedEmptyInput,
758
759 #[snafu(display("Exceeded maximum parse depth"))]
761 ExceedsMaxParseDepth,
762}
763
764#[derive(Snafu, Debug)]
766#[snafu(visibility(pub))]
767#[non_exhaustive]
768pub enum BerDecodeErrorKind {
769 #[snafu(display("Indefinite length encountered but not allowed"))]
771 IndefiniteLengthNotAllowed,
772 #[snafu(display("Invalid constructed identifier for ASN.1 value: not primitive"))]
774 InvalidConstructedIdentifier,
775 #[snafu(display("Invalid date string: {}", msg))]
777 InvalidDate {
778 msg: alloc::string::String,
780 },
781 #[snafu(display("Invalid object identifier with missing or corrupt root nodes"))]
783 InvalidObjectIdentifier,
784 #[snafu(display("Expected {:?} tag, actual tag: {:?}", expected, actual))]
786 MismatchedTag {
787 expected: Tag,
789 actual: Tag,
791 },
792}
793
794impl BerDecodeErrorKind {
795 #[must_use]
797 pub fn invalid_date(msg: alloc::string::String) -> CodecDecodeError {
798 CodecDecodeError::Ber(Self::InvalidDate { msg })
799 }
800 pub fn assert_tag(expected: Tag, actual: Tag) -> core::result::Result<(), DecodeError> {
802 if expected == actual {
803 Ok(())
804 } else {
805 Err(BerDecodeErrorKind::MismatchedTag { expected, actual }.into())
806 }
807 }
808}
809#[derive(Snafu, Debug)]
812#[snafu(visibility(pub))]
813#[non_exhaustive]
814pub enum CerDecodeErrorKind {}
815
816#[derive(Snafu, Debug)]
818#[snafu(visibility(pub))]
819#[non_exhaustive]
820pub enum DerDecodeErrorKind {
821 #[snafu(display("Constructed encoding encountered but not allowed"))]
823 ConstructedEncodingNotAllowed,
824}
825
826#[derive(Snafu, Debug)]
828#[snafu(visibility(pub))]
829#[non_exhaustive]
830pub enum JerDecodeErrorKind {
831 #[snafu(display("Unexpected end of input while decoding JER"))]
833 EndOfInput {},
834 #[snafu(display(
836 "Found mismatching JSON value. Expected type: {}. Found value: {}",
837 needed,
838 found
839 ))]
840 TypeMismatch {
841 needed: &'static str,
843 found: alloc::string::String,
845 },
846 #[snafu(display("Found invalid byte in bit string: {parse_int_err}"))]
848 InvalidJerBitstring {
849 parse_int_err: ParseIntError,
851 },
852 #[snafu(display("Found invalid character in octet string"))]
854 InvalidJerOctetString {},
855 #[snafu(display("Failed to construct OID from value {value}",))]
857 InvalidOIDString {
858 value: serde_json::Value,
860 },
861 #[snafu(display("Found invalid enumerated discriminant {discriminant}",))]
863 InvalidEnumDiscriminant {
864 discriminant: alloc::string::String,
866 },
867}
868
869impl JerDecodeErrorKind {
870 #[must_use]
872 pub fn eoi() -> CodecDecodeError {
873 CodecDecodeError::Jer(JerDecodeErrorKind::EndOfInput {})
874 }
875}
876
877#[derive(Snafu, Debug)]
880#[snafu(visibility(pub))]
881#[non_exhaustive]
882pub enum UperDecodeErrorKind {}
883
884#[derive(Snafu, Debug)]
887#[snafu(visibility(pub))]
888#[non_exhaustive]
889pub enum AperDecodeErrorKind {}
890
891#[derive(Snafu, Debug)]
893#[snafu(visibility(pub))]
894#[non_exhaustive]
895pub enum XerDecodeErrorKind {
896 #[snafu(display("Unexpected end of input while decoding XER"))]
897 EndOfXmlInput {},
899 #[snafu(display(
900 "Found mismatching XML value. Expected type: {}. Found value: {}.",
901 needed,
902 found
903 ))]
904 XmlTypeMismatch {
906 needed: &'static str,
908 found: alloc::string::String,
910 },
911 #[snafu(display("Found invalid character in octet string"))]
912 InvalidXerOctetstring {
914 parse_int_err: ParseIntError,
916 },
917 #[snafu(display("Encountered invalid value: {details}"))]
918 InvalidInput {
920 details: &'static str,
922 },
923 #[snafu(display("Found invalid open type encoding: {inner_err}"))]
924 InvalidOpenType {
926 inner_err: xml_no_std::writer::Error,
928 },
929 #[snafu(display("XML parser error: {details}"))]
930 XmlParser {
932 details: alloc::string::String,
934 },
935 #[snafu(display("Error matching tag names: expected {needed}, found {found}"))]
936 XmlTag {
938 needed: alloc::string::String,
940 found: alloc::string::String,
942 },
943 #[snafu(display("Encoding violates ITU-T X.693 (02/2021): {details}"))]
944 SpecViolation {
946 details: alloc::string::String,
948 },
949}
950
951#[derive(Snafu, Debug)]
953#[snafu(visibility(pub))]
954#[non_exhaustive]
955pub enum OerDecodeErrorKind {
956 #[snafu(display("Invalid tag class when decoding choice: actual {:?}", class))]
958 InvalidTagClassOnChoice {
959 class: u8,
961 },
962 #[snafu(display("Invalid tag number when decoding Choice: {value}"))]
964 InvalidTagNumberOnChoice {
965 value: u32,
967 },
968 #[snafu(display(
970 "Tag not found from the variants of the platform when decoding Choice. Tag: {value}, extensible status: {is_extensible}"
971 ))]
972 InvalidTagVariantOnChoice {
973 value: Tag,
975 is_extensible: bool,
977 },
978
979 InvalidExtensionHeader {
981 msg: alloc::string::String,
983 },
984 #[snafu(display("Invalid BitString: {msg}"))]
986 InvalidOerBitString {
987 msg: alloc::string::String,
989 },
990 #[snafu(display("Invalid preamble: {msg}"))]
992 InvalidPreamble {
993 msg: alloc::string::String,
995 },
996}
997
998impl OerDecodeErrorKind {
999 #[must_use]
1000 pub fn invalid_tag_number_on_choice(value: u32) -> DecodeError {
1002 CodecDecodeError::Oer(Self::InvalidTagNumberOnChoice { value }).into()
1003 }
1004 #[must_use]
1005 pub fn invalid_tag_variant_on_choice(value: Tag, is_extensible: bool) -> DecodeError {
1007 CodecDecodeError::Oer(Self::InvalidTagVariantOnChoice {
1008 value,
1009 is_extensible,
1010 })
1011 .into()
1012 }
1013
1014 #[must_use]
1016 pub fn invalid_extension_header(msg: alloc::string::String) -> DecodeError {
1017 CodecDecodeError::Oer(Self::InvalidExtensionHeader { msg }).into()
1018 }
1019 #[must_use]
1021 pub fn invalid_bit_string(msg: alloc::string::String) -> DecodeError {
1022 CodecDecodeError::Oer(Self::InvalidOerBitString { msg }).into()
1023 }
1024 #[must_use]
1026 pub fn invalid_preamble(msg: alloc::string::String) -> DecodeError {
1027 CodecDecodeError::Oer(Self::InvalidPreamble { msg }).into()
1028 }
1029}
1030
1031#[derive(Snafu, Debug)]
1033#[snafu(visibility(pub))]
1034#[non_exhaustive]
1035pub enum CoerDecodeErrorKind {
1036 #[snafu(display(
1038 "Invalid Canonical Octet Encoding, not encoded as the smallest possible number of octets: {msg}"
1039 ))]
1040 NotValidCanonicalEncoding {
1041 msg: alloc::string::String,
1043 },
1044}
1045
1046impl crate::de::Error for DecodeError {
1047 fn custom<D: core::fmt::Display>(msg: D, codec: Codec) -> Self {
1048 Self::from_kind(
1049 DecodeErrorKind::Custom {
1050 msg: msg.to_string(),
1051 },
1052 codec,
1053 )
1054 }
1055 fn incomplete(needed: nom::Needed, codec: Codec) -> Self {
1056 Self::from_kind(DecodeErrorKind::Incomplete { needed }, codec)
1057 }
1058
1059 fn exceeds_max_length(length: num_bigint::BigUint, codec: Codec) -> Self {
1060 Self::from_kind(DecodeErrorKind::ExceedsMaxLength { length }, codec)
1061 }
1062
1063 fn missing_field(name: &'static str, codec: Codec) -> Self {
1064 Self::from_kind(DecodeErrorKind::MissingField { name }, codec)
1065 }
1066
1067 fn no_valid_choice(name: &'static str, codec: Codec) -> Self {
1068 Self::from_kind(DecodeErrorKind::NoValidChoice { name }, codec)
1069 }
1070
1071 fn field_error(name: &'static str, nested: DecodeError, codec: Codec) -> Self {
1072 Self::from_kind(
1073 DecodeErrorKind::FieldError {
1074 name,
1075 nested: Box::new(nested),
1076 },
1077 codec,
1078 )
1079 }
1080
1081 fn duplicate_field(name: &'static str, codec: Codec) -> Self {
1082 Self::from_kind(DecodeErrorKind::DuplicateField { name }, codec)
1083 }
1084 fn unknown_field(index: usize, tag: Tag, codec: Codec) -> Self {
1085 Self::from_kind(DecodeErrorKind::UnknownField { index, tag }, codec)
1086 }
1087}
1088
1089#[cfg(test)]
1090mod tests {
1091 use crate::prelude::*;
1092 #[test]
1093 fn test_ber_decode_date() {
1094 use crate::error::{DecodeError, DecodeErrorKind};
1095 let data = [
1097 23, 17, 50, 51, 48, 49, 50, 50, 49, 51, 48, 48, 48, 48, 45, 48, 53, 48, 90,
1098 ];
1099 let result = crate::ber::decode::<UtcTime>(&data);
1100 match result {
1101 Err(DecodeError { kind, .. }) => {
1102 if let DecodeErrorKind::CodecSpecific {
1103 inner:
1104 crate::error::CodecDecodeError::Ber(
1105 crate::error::BerDecodeErrorKind::InvalidDate { msg },
1106 ),
1107 ..
1108 } = *kind
1109 {
1110 assert_eq!(msg, "230122130000-050Z");
1111 } else {
1112 panic!("Unexpected error kind: {kind}");
1114 }
1115 }
1116 Ok(_) => panic!("Expected error"),
1117 }
1118 }
1119 #[test]
1120 fn test_uper_missing_choice_index() {
1121 use crate as rasn;
1122 use crate::Codec;
1123 use crate::error::{DecodeError, DecodeErrorKind};
1124 #[derive(AsnType, Decode, Debug, PartialEq)]
1125 #[rasn(choice, automatic_tags)]
1126 enum MyChoice {
1127 Normal(Integer),
1128 High(Integer),
1129 Medium(Integer),
1130 }
1131 let data = [192, 128, 83, 64];
1133 let result = Codec::Uper.decode_from_binary::<MyChoice>(&data);
1134 match result {
1135 Ok(_) => {
1136 panic!("Unexpected OK!");
1137 }
1138 Err(DecodeError { kind, .. }) => {
1139 if let DecodeErrorKind::ChoiceIndexNotFound { index, .. } = *kind {
1140 assert_eq!(index, 3);
1141 } else {
1142 panic!("Unexpected error kind: {kind}");
1144 }
1145 }
1146 }
1147 }
1148}