rasn/error/
decode.rs

1//! Error types associated with decoding from ASN.1 codecs.
2
3use 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::de::Error;
13use crate::types::{constraints::Bounded, variants::Variants, Tag};
14use crate::Codec;
15use num_bigint::BigInt;
16
17/// Variants for every codec-specific `DecodeError` kind.
18#[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
33macro_rules! impl_from {
34    ($variant:ident, $error_kind:ty) => {
35        impl From<$error_kind> for DecodeError {
36            fn from(error: $error_kind) -> Self {
37                Self::from_codec_kind(CodecDecodeError::$variant(error))
38            }
39        }
40    };
41}
42
43// implement From for each variant of CodecDecodeError into DecodeError
44impl_from!(Ber, BerDecodeErrorKind);
45impl_from!(Cer, CerDecodeErrorKind);
46impl_from!(Der, DerDecodeErrorKind);
47impl_from!(Uper, UperDecodeErrorKind);
48impl_from!(Aper, AperDecodeErrorKind);
49impl_from!(Jer, JerDecodeErrorKind);
50impl_from!(Oer, OerDecodeErrorKind);
51impl_from!(Coer, CoerDecodeErrorKind);
52impl_from!(Xer, XerDecodeErrorKind);
53
54impl From<CodecDecodeError> for DecodeError {
55    fn from(error: CodecDecodeError) -> Self {
56        Self::from_codec_kind(error)
57    }
58}
59
60/// An error type for failed decoding for every decoder.
61/// Abstracts over the different generic and codec-specific errors.
62///
63/// `kind` field is used to determine the kind of error that occurred.
64/// `codec` field is used to determine the codec that failed.
65/// `backtrace` field is used to determine the backtrace of the error.
66///
67/// There is `Kind::CodecSpecific` variant which wraps the codec-specific
68/// errors as `CodecEncodeError` type.
69///
70/// # Example
71/// ```rust
72/// use nom::Needed;
73/// use rasn::{Codec, error::DecodeErrorKind, prelude::*};
74///
75/// #[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq)]
76/// #[rasn(delegate)]
77/// struct MyString(pub VisibleString);
78///
79/// fn main() {
80///     // Hello, World! in decimal bytes with trailing zeros
81///     // Below sample requires that `backtraces` feature is enabled
82///     let hello_data = vec![
83///         13, 145, 151, 102, 205, 235, 16, 119, 223, 203, 102, 68, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
84///         0,
85///     ];
86///     // Initially parse the first 2 bytes for Error demonstration purposes
87///     let mut total = 2;
88///
89///     loop {
90///         let decoded = Codec::Uper.decode_from_binary::<MyString>(&hello_data[0..hello_data.len().min(total)]);
91///         match decoded {
92///             Ok(succ) => {
93///                 println!("Successful decoding!");
94///                 println!("Decoded string: {}", succ.0);
95///                 break;
96///             }
97///             Err(e) => {
98///                 // e is DecodeError, kind is boxed
99///                 match *e.kind {
100///                     DecodeErrorKind::Incomplete { needed } => {
101///                         println!("Codec error source: {}", e.codec);
102///                         println!("Error kind: {}", e.kind);
103///                         // Here you need to know, that VisibleString has width of 7 bits and UPER parses input
104///                         // as bits, if you want to build logic around it, and feed exactly the correct amount of data.
105///                         // Usually you might need to just provide one byte at time instead when something is missing, since
106///                         // inner logic might not be known to you, and data structures can get complex.
107///                         total += match needed {
108///                             Needed::Size(n) => {
109///                                 let missing_bytes = n.get() / 7;
110///                                 missing_bytes
111///
112///                             }
113///                             _ => {
114///                                 #[cfg(feature = "backtraces")]
115///                                 println!("Backtrace:\n{:?}", e.backtrace);
116///                                 panic!("Unexpected error! {e:?}");
117///                             }
118///                         }
119///                     }
120///                     k => {
121///                         #[cfg(feature = "backtraces")]
122///                         println!("Backtrace:\n{:?}", e.backtrace);
123///                         panic!("Unexpected error! {k:?}");
124///                     }
125///                 }
126///             }
127///         }
128///     }
129/// }
130///```
131/// The previous will produce something like following:
132/// ```text
133/// Codec error: UPER
134/// Error kind: Need more BITS to continue: (Size(83)).
135/// Successful decoding!
136/// Decoded string: Hello, world!
137/// ```
138#[derive(Debug)]
139#[allow(clippy::module_name_repetitions)]
140pub struct DecodeError {
141    /// The kind of decoding error received.
142    pub kind: Box<DecodeErrorKind>,
143    /// The codec that returned the error.
144    pub codec: Codec,
145    /// The backtrace associated with the error.
146    #[cfg(feature = "backtraces")]
147    pub backtrace: Backtrace,
148}
149
150impl core::fmt::Display for DecodeError {
151    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
152        writeln!(f, "Error Kind: {}", self.kind)?;
153        writeln!(f, "Codec: {}", self.codec)?;
154        #[cfg(feature = "backtraces")]
155        write!(f, "\nBacktrace:\n{}", self.backtrace)?;
156        Ok(())
157    }
158}
159
160impl DecodeError {
161    /// Creates a wrapper around a permitted alphabet error from a given codec.
162    #[must_use]
163    pub fn permitted_alphabet_error(reason: PermittedAlphabetError, codec: Codec) -> Self {
164        Self::from_kind(DecodeErrorKind::PermittedAlphabetError { reason }, codec)
165    }
166
167    /// Creates a wrapper around a size error from a given codec.
168    #[must_use]
169    pub fn size_constraint_not_satisfied(
170        size: Option<usize>,
171        expected: alloc::string::String,
172        codec: Codec,
173    ) -> Self {
174        Self::from_kind(
175            DecodeErrorKind::SizeConstraintNotSatisfied { size, expected },
176            codec,
177        )
178    }
179
180    /// Creates a wrapper around a value error from a given codec.
181    #[must_use]
182    pub fn value_constraint_not_satisfied(
183        value: BigInt,
184        expected: Bounded<i128>,
185        codec: Codec,
186    ) -> Self {
187        Self::from_kind(
188            DecodeErrorKind::ValueConstraintNotSatisfied { value, expected },
189            codec,
190        )
191    }
192    /// Creates a wrapper around a inner subtype constraint error from a given codec.
193    /// This is mainly used by standards.
194    #[must_use]
195    pub fn inner_subtype_constraint_not_satisfied(
196        reason: super::InnerSubtypeConstraintError,
197        codec: Codec,
198    ) -> Self {
199        Self::from_kind(
200            DecodeErrorKind::InnerSubtypeConstraintNotSatisfied { reason },
201            codec,
202        )
203    }
204
205    /// Creates a wrapper around a discriminant value error from a given codec.
206    #[must_use]
207    pub fn discriminant_value_not_found(discriminant: isize, codec: Codec) -> Self {
208        Self::from_kind(
209            DecodeErrorKind::DiscriminantValueNotFound { discriminant },
210            codec,
211        )
212    }
213
214    /// Creates a wrapper around a range value error from a given codec.
215    #[must_use]
216    pub fn range_exceeds_platform_width(needed: u32, present: u32, codec: Codec) -> Self {
217        Self::from_kind(
218            DecodeErrorKind::RangeExceedsPlatformWidth { needed, present },
219            codec,
220        )
221    }
222
223    /// Creates a wrapper around a fixed string conversion error from a given codec.
224    #[must_use]
225    pub fn fixed_string_conversion_failed(
226        tag: Tag,
227        actual: usize,
228        expected: usize,
229        codec: Codec,
230    ) -> Self {
231        Self::from_kind(
232            DecodeErrorKind::FixedStringConversionFailed {
233                tag,
234                actual,
235                expected,
236            },
237            codec,
238        )
239    }
240
241    /// Creates a wrapper around a sequence item error from a given codec.
242    #[must_use]
243    pub fn incorrect_item_number_in_sequence(expected: usize, actual: usize, codec: Codec) -> Self {
244        Self::from_kind(
245            DecodeErrorKind::IncorrectItemNumberInSequence { expected, actual },
246            codec,
247        )
248    }
249
250    /// Creates a wrapper around a integer overflow error from a given codec.
251    #[must_use]
252    pub fn integer_overflow(max_width: u32, codec: Codec) -> Self {
253        Self::from_kind(DecodeErrorKind::IntegerOverflow { max_width }, codec)
254    }
255
256    /// Creates a wrapper around a integer conversion error from a given codec.
257    #[must_use]
258    pub fn integer_type_conversion_failed(msg: alloc::string::String, codec: Codec) -> Self {
259        Self::from_kind(DecodeErrorKind::IntegerTypeConversionFailed { msg }, codec)
260    }
261
262    /// Creates a wrapper around a invalid bit string error from a given codec.
263    #[must_use]
264    pub fn invalid_bit_string(bits: u8, codec: Codec) -> Self {
265        Self::from_kind(DecodeErrorKind::InvalidBitString { bits }, codec)
266    }
267
268    /// Creates a wrapper around a missing tag error from a given codec.
269    #[must_use]
270    pub fn missing_tag_class_or_value_in_sequence_or_set(
271        class: crate::types::Class,
272        value: u32,
273        codec: Codec,
274    ) -> Self {
275        Self::from_kind(
276            DecodeErrorKind::MissingTagClassOrValueInSequenceOrSet { class, value },
277            codec,
278        )
279    }
280
281    /// Creates a wrapper around a unexpected non-extensible type error from a given codec.
282    #[must_use]
283    pub fn type_not_extensible(codec: Codec) -> Self {
284        Self::from_kind(DecodeErrorKind::TypeNotExtensible, codec)
285    }
286
287    /// Creates a wrapper around a parser error from a given codec.
288    #[must_use]
289    pub fn parser_fail(msg: alloc::string::String, codec: Codec) -> Self {
290        DecodeError::from_kind(DecodeErrorKind::Parser { msg }, codec)
291    }
292
293    /// Creates a wrapper around using `REAL` with unsupported codecs.
294    #[must_use]
295    pub fn real_not_supported(codec: Codec) -> Self {
296        DecodeError::from_kind(DecodeErrorKind::RealNotSupported, codec)
297    }
298
299    /// Creates a wrapper around a missing required extension error from a given codec.
300    #[must_use]
301    pub fn required_extension_not_present(tag: Tag, codec: Codec) -> Self {
302        Self::from_kind(DecodeErrorKind::RequiredExtensionNotPresent { tag }, codec)
303    }
304
305    /// Creates a wrapper around a missing enum index error from a given codec.
306    #[must_use]
307    pub fn enumeration_index_not_found(index: usize, extended_list: bool, codec: Codec) -> Self {
308        Self::from_kind(
309            DecodeErrorKind::EnumerationIndexNotFound {
310                index,
311                extended_list,
312            },
313            codec,
314        )
315    }
316
317    /// Creates a wrapper around a choice index exceeding platform width error from a given codec.
318    #[must_use]
319    pub fn choice_index_exceeds_platform_width(
320        needed: u32,
321        present: DecodeError,
322        codec: Codec,
323    ) -> Self {
324        Self::from_kind(
325            DecodeErrorKind::ChoiceIndexExceedsPlatformWidth { needed, present },
326            codec,
327        )
328    }
329
330    /// Creates a wrapper around a length exceeding platform width error from a given codec.
331    #[must_use]
332    pub fn length_exceeds_platform_width(msg: alloc::string::String, codec: Codec) -> Self {
333        Self::from_kind(DecodeErrorKind::LengthExceedsPlatformWidth { msg }, codec)
334    }
335
336    /// Creates a wrapper around a missing choice index error from a given codec.
337    #[must_use]
338    pub fn choice_index_not_found(index: usize, variants: Variants, codec: Codec) -> Self {
339        Self::from_kind(
340            DecodeErrorKind::ChoiceIndexNotFound { index, variants },
341            codec,
342        )
343    }
344
345    /// Creates a wrapper around a string conversion error from a given codec.
346    #[must_use]
347    pub fn string_conversion_failed(tag: Tag, msg: alloc::string::String, codec: Codec) -> Self {
348        Self::from_kind(DecodeErrorKind::StringConversionFailed { tag, msg }, codec)
349    }
350
351    /// Creates a wrapper around unexpected extra data error from a given codec.
352    #[must_use]
353    pub fn unexpected_extra_data(length: usize, codec: Codec) -> Self {
354        Self::from_kind(DecodeErrorKind::UnexpectedExtraData { length }, codec)
355    }
356
357    /// Creates a wrapper around unexpected empty input error from a given codec.
358    #[must_use]
359    pub fn unexpected_empty_input(codec: Codec) -> Self {
360        Self::from_kind(DecodeErrorKind::UnexpectedEmptyInput, codec)
361    }
362
363    /// Checks whether the length matches, and returns an error if not.
364    pub fn assert_length(
365        expected: usize,
366        actual: usize,
367        codec: Codec,
368    ) -> core::result::Result<(), DecodeError> {
369        if expected == actual {
370            Ok(())
371        } else {
372            Err(DecodeError::from_kind(
373                DecodeErrorKind::MismatchedLength { expected, actual },
374                codec,
375            ))
376        }
377    }
378
379    pub(crate) fn map_nom_err<T: core::fmt::Debug>(
380        error: nom::Err<nom::error::Error<T>>,
381        codec: Codec,
382    ) -> DecodeError {
383        let msg = match error {
384            nom::Err::Incomplete(needed) => return DecodeError::incomplete(needed, codec),
385            err => alloc::format!("Parsing Failure: {err}"),
386        };
387        DecodeError::parser_fail(msg, codec)
388    }
389
390    /// Creates a new error from a given decode error kind and codec.
391    #[must_use]
392    pub fn from_kind(kind: DecodeErrorKind, codec: Codec) -> Self {
393        Self {
394            kind: Box::new(kind),
395            codec,
396            #[cfg(feature = "backtraces")]
397            backtrace: Backtrace::generate(),
398        }
399    }
400
401    #[must_use]
402    fn from_codec_kind(inner: CodecDecodeError) -> Self {
403        let codec = match inner {
404            CodecDecodeError::Ber(_) => crate::Codec::Ber,
405            #[allow(unreachable_patterns)]
406            CodecDecodeError::Cer(_) => crate::Codec::Cer,
407            CodecDecodeError::Der(_) => crate::Codec::Der,
408            #[allow(unreachable_patterns)]
409            CodecDecodeError::Uper(_) => crate::Codec::Uper,
410            #[allow(unreachable_patterns)]
411            CodecDecodeError::Aper(_) => crate::Codec::Aper,
412            CodecDecodeError::Jer(_) => crate::Codec::Jer,
413            CodecDecodeError::Oer(_) => crate::Codec::Oer,
414            CodecDecodeError::Coer(_) => crate::Codec::Coer,
415            CodecDecodeError::Xer(_) => crate::Codec::Xer,
416        };
417        Self {
418            kind: Box::new(DecodeErrorKind::CodecSpecific { inner }),
419            codec,
420            #[cfg(feature = "backtraces")]
421            backtrace: Backtrace::generate(),
422        }
423    }
424}
425
426impl core::error::Error for DecodeError {}
427
428/// `DecodeError` kinds which are common for all codecs.
429#[derive(Snafu)]
430#[snafu(visibility(pub))]
431#[derive(Debug)]
432#[non_exhaustive]
433pub enum DecodeErrorKind {
434    /// Permitted alphabet constraint wasn't satisfied.
435    #[snafu(display("Alphabet constraint not satisfied {}", reason))]
436    PermittedAlphabetError {
437        /// The reason the constraint wasn't satisfied.
438        reason: PermittedAlphabetError,
439    },
440
441    /// Size constraint wasn't satisfied.
442    #[snafu(display("Size constraint not satisfied: expected: {expected}; actual: {size:?}"))]
443    SizeConstraintNotSatisfied {
444        /// Actual sie of the data
445        size: Option<usize>,
446        /// Expected size by the constraint
447        expected: alloc::string::String,
448    },
449
450    /// Value constraint wasn't satisfied.
451    #[snafu(display("Value constraint not satisfied: expected: {expected}; actual: {value}"))]
452    ValueConstraintNotSatisfied {
453        /// Actual value of the data
454        value: BigInt,
455        /// Expected value by the constraint
456        expected: Bounded<i128>,
457    },
458    /// Inner subtype constraint not satisfied.
459    #[snafu(display("Inner subtype constraint not satisfied: {reason}"))]
460    InnerSubtypeConstraintNotSatisfied {
461        /// The reason the constraint wasn't satisfied.
462        reason: super::InnerSubtypeConstraintError,
463    },
464
465    /// Codec specific error.
466    #[snafu(display("Wrapped codec-specific decode error"))]
467    CodecSpecific {
468        /// The inner error type.
469        inner: CodecDecodeError,
470    },
471
472    /// Enumeration index didn't match any variant.
473    #[snafu(display(
474        "Enumeration index '{}' did not match any variant. Extended list: {}",
475        index,
476        extended_list
477    ))]
478    EnumerationIndexNotFound {
479        /// The found index of the enumerated variant.
480        index: usize,
481        /// Whether the index was checked from the extended variants.
482        extended_list: bool,
483    },
484
485    /// Choice index didn't match any variant.
486    #[snafu(display("choice index '{index}' did not match any variant"))]
487    ChoiceIndexNotFound {
488        /// The found index of the choice variant.
489        index: usize,
490        /// The variants checked for presence.
491        variants: Variants,
492    },
493
494    /// Choice index exceeds maximum possible address width.
495    #[snafu(display("integer range larger than possible to address on this platform. needed: {needed} present: {present}"))]
496    ChoiceIndexExceedsPlatformWidth {
497        /// Amount of bytes needed.
498        needed: u32,
499        /// Inner error
500        present: DecodeError,
501    },
502
503    /// Uncategorised error.
504    #[snafu(display("Custom: {}", msg))]
505    Custom {
506        /// The error's message.
507        msg: alloc::string::String,
508    },
509
510    /// Discriminant index didn't match any variant.
511    #[snafu(display("Discriminant value '{}' did not match any variant", discriminant))]
512    DiscriminantValueNotFound {
513        /// The found value of the discriminant
514        discriminant: isize,
515    },
516
517    /// Duplicate fields found.
518    #[snafu(display("Duplicate field for `{}`", name))]
519    DuplicateField {
520        /// The field's name.
521        name: &'static str,
522    },
523
524    /// Exceeds maxmium allowed length.
525    #[snafu(display("Expected maximum of {} items", length))]
526    ExceedsMaxLength {
527        /// The maximum length.
528        length: num_bigint::BigUint,
529    },
530
531    ///  More than `usize::MAX` number of data requested.
532    #[snafu(display("Length of the incoming data is either exceeds platform address width."))]
533    LengthExceedsPlatformWidth {
534        /// The specific message of the length error.
535        msg: alloc::string::String,
536    },
537
538    /// An error when decoding a field in a constructed type.
539    #[snafu(display("Error when decoding field `{}`: {}", name, nested))]
540    FieldError {
541        /// The field's name.
542        name: &'static str,
543        /// The underlying error type.
544        nested: Box<DecodeError>,
545    },
546
547    /// Input is provided as BIT slice for nom in UPER/APER.
548    /// On BER/CER/DER/OER/COER it is a BYTE slice.
549    /// Hence, `needed` field can describe either bits or bytes depending on the codec.
550    #[snafu(display("Need more data to continue: ({:?}).", needed))]
551    Incomplete {
552        /// Amount of bits/bytes needed.
553        needed: nom::Needed,
554    },
555
556    /// Invalid item number in sequence.
557    #[snafu(display(
558        "Invalid item number in Sequence: expected {}, actual {}",
559        expected,
560        actual
561    ))]
562    IncorrectItemNumberInSequence {
563        /// The expected item number.
564        expected: usize,
565        /// The actual item number.
566        actual: usize,
567    },
568
569    /// Integer conversion overflow.
570    #[snafu(display("Actual integer larger than expected {} bits", max_width))]
571    IntegerOverflow {
572        /// The maximum integer width.
573        max_width: u32,
574    },
575
576    /// Integer conversion failure.
577    #[snafu(display("Failed to cast integer to another integer type: {msg} "))]
578    IntegerTypeConversionFailed {
579        /// The reason the conversion failed.
580        msg: alloc::string::String,
581    },
582
583    /// Real conversion failure.
584    #[snafu(display("Invalid real encoding"))]
585    InvalidRealEncoding,
586
587    /// Decoder doesn't support REAL
588    #[snafu(display("Decoder doesn't support REAL types"))]
589    RealNotSupported,
590
591    /// BitString contains an invalid amount of unused bits.
592    #[snafu(display("BitString contains an invalid amount of unused bits: {}", bits))]
593    InvalidBitString {
594        /// The amount of invalid bits.
595        bits: u8,
596    },
597
598    /// BOOL value is not `0` or `0xFF`.
599    #[snafu(display(
600        "Bool value is not `0` or `0xFF` as canonical requires. Actual: {}",
601        value
602    ))]
603    InvalidBool {
604        /// The invalid bool value.
605        value: u8,
606    },
607
608    /// Length of Length cannot be zero.
609    #[snafu(display("Length of Length cannot be zero"))]
610    ZeroLengthOfLength,
611    /// The length does not match what was expected.
612    #[snafu(display("Expected {:?} bytes, actual length: {:?}", expected, actual))]
613    MismatchedLength {
614        /// The expected length.
615        expected: usize,
616        /// The actual length.
617        actual: usize,
618    },
619
620    /// Missing field in a sequence.
621    #[snafu(display("Missing field `{}`", name))]
622    MissingField {
623        /// The field's name.
624        name: &'static str,
625    },
626    /// When there is a mismatch between the expected and actual tag class or `value`.
627    #[snafu(display("Expected class: {}, value: {} in sequence or set Missing tag class or value in sequence or set", class, value))]
628    MissingTagClassOrValueInSequenceOrSet {
629        /// The tag's class.
630        class: crate::types::Class,
631        /// The tag's value.
632        value: u32,
633    },
634
635    /// The range of the integer exceeds the platform width.
636    #[snafu(display("integer range larger than possible to address on this platform. needed: {needed} present: {present}"))]
637    RangeExceedsPlatformWidth {
638        /// Amount of bytes needed.
639        needed: u32,
640        /// Amount of bytes needed.
641        present: u32,
642    },
643    /// A specific required extension not present.
644    #[snafu(display("Extension with class `{}` and tag `{}` required, but not present", tag.class, tag.value))]
645    RequiredExtensionNotPresent {
646        /// The tag of the required extension.
647        tag: crate::types::Tag,
648    },
649    /// General error when parsing data.
650    #[snafu(display("Error in Parser: {}", msg))]
651    Parser {
652        /// The error's message.
653        msg: alloc::string::String,
654    },
655    /// General error for failed ASN.1 string conversion from bytes.
656    #[snafu(display(
657        "Failed to convert byte array into valid ASN.1 string. String type as tag: {} Error: {}",
658        tag,
659        msg
660    ))]
661    StringConversionFailed {
662        /// Universal tag of the string type.
663        tag: Tag,
664        /// The error's message.
665        msg: alloc::string::String,
666    },
667    /// General error for failed ASN.1 fixed-sized string conversion from bytes.
668    #[snafu(display(
669    "Failed to convert byte array into valid fixed-sized ASN.1 string. String type as tag: {}, actual: {}, expected: {}",
670    tag,
671    actual,
672    expected
673    ))]
674    FixedStringConversionFailed {
675        /// Tag of the string type.
676        tag: Tag,
677        /// Expected length
678        expected: usize,
679        /// Actual length
680        actual: usize,
681    },
682    /// An error when the choice cannot be created from the given variant.
683    #[snafu(display("No valid choice for `{}`", name))]
684    NoValidChoice {
685        /// The field's name.
686        name: &'static str,
687    },
688
689    /// An error when the type is not extensible when it should.
690    #[snafu(display("Attempted to decode extension on non-extensible type"))]
691    TypeNotExtensible,
692    /// Unexpected extra data found.
693    #[snafu(display("Unexpected extra data found: length `{}` bytes", length))]
694    UnexpectedExtraData {
695        /// The amount of garbage data.
696        length: usize,
697    },
698    /// An error when a unknown field is found when decoding sequence.
699    #[snafu(display("Unknown field with index {} and tag {}", index, tag))]
700    UnknownField {
701        /// Index of the field.
702        index: usize,
703        /// Tag of the field.
704        tag: Tag,
705    },
706    /// An error when there should be more data but it is not present.
707    #[snafu(display(
708        "No input was provided where expected in the given SEQUENCE or INTEGER type"
709    ))]
710    UnexpectedEmptyInput,
711}
712
713/// `DecodeError` kinds of `Kind::CodecSpecific` which are specific for BER.
714#[derive(Snafu, Debug)]
715#[snafu(visibility(pub))]
716#[non_exhaustive]
717pub enum BerDecodeErrorKind {
718    /// An error when the length is not definite.
719    #[snafu(display("Indefinite length encountered but not allowed."))]
720    IndefiniteLengthNotAllowed,
721    /// An error if the value is not primitive when required.
722    #[snafu(display("Invalid constructed identifier for ASN.1 value: not primitive."))]
723    InvalidConstructedIdentifier,
724    /// Invalid date.
725    #[snafu(display("Invalid date string: {}", msg))]
726    InvalidDate {
727        /// The reason as string
728        msg: alloc::string::String,
729    },
730    /// An error when the object identifier is invalid.
731    #[snafu(display("Invalid object identifier with missing or corrupt root nodes."))]
732    InvalidObjectIdentifier,
733    /// The tag does not match what was expected.
734    #[snafu(display("Expected {:?} tag, actual tag: {:?}", expected, actual))]
735    MismatchedTag {
736        /// The expected tag.
737        expected: Tag,
738        /// The actual tag.
739        actual: Tag,
740    },
741}
742
743impl BerDecodeErrorKind {
744    /// A helper function to create an error [BerDecodeErrorKind::InvalidDate].
745    #[must_use]
746    pub fn invalid_date(msg: alloc::string::String) -> CodecDecodeError {
747        CodecDecodeError::Ber(Self::InvalidDate { msg })
748    }
749    /// A helper function to create an error [BerDecodeErrorKind::MismatchedTag].
750    pub fn assert_tag(expected: Tag, actual: Tag) -> core::result::Result<(), DecodeError> {
751        if expected == actual {
752            Ok(())
753        } else {
754            Err(BerDecodeErrorKind::MismatchedTag { expected, actual }.into())
755        }
756    }
757}
758// TODO check if there are more codec-specific errors here
759/// `DecodeError` kinds of `Kind::CodecSpecific` which are specific for CER.
760#[derive(Snafu, Debug)]
761#[snafu(visibility(pub))]
762#[non_exhaustive]
763pub enum CerDecodeErrorKind {}
764
765/// `DecodeError` kinds of `Kind::CodecSpecific` which are specific for DER.
766#[derive(Snafu, Debug)]
767#[snafu(visibility(pub))]
768#[non_exhaustive]
769pub enum DerDecodeErrorKind {
770    /// An error when constructed encoding encountered but not allowed.
771    #[snafu(display("Constructed encoding encountered but not allowed."))]
772    ConstructedEncodingNotAllowed,
773}
774
775/// An error that occurred when decoding JER.
776#[derive(Snafu, Debug)]
777#[snafu(visibility(pub))]
778#[non_exhaustive]
779pub enum JerDecodeErrorKind {
780    /// An error when the end of input is reached, but more data is needed.
781    #[snafu(display("Unexpected end of input while decoding JER JSON."))]
782    EndOfInput {},
783    /// An error when the JSON type is not the expected type.
784    #[snafu(display(
785        "Found mismatching JSON value. Expected type {}. Found value {}.",
786        needed,
787        found
788    ))]
789    TypeMismatch {
790        /// Expected JSON type.
791        needed: &'static str,
792        /// Found JSON value.
793        found: alloc::string::String,
794    },
795    /// An error when the JSON value is not a valid bit string.
796    #[snafu(display("Found invalid byte in bit string. {parse_int_err}"))]
797    InvalidJerBitstring {
798        /// The error that occurred when parsing the BitString byte.
799        parse_int_err: ParseIntError,
800    },
801    /// An error when the JSON value is not a valid octet string.
802    #[snafu(display("Found invalid character in octet string."))]
803    InvalidJerOctetString {},
804    /// An error when the JSON value is not a valid OID string.
805    #[snafu(display("Failed to construct OID from value {value}",))]
806    InvalidOIDString {
807        /// The JSON value that could not be converted to an OID.
808        value: serde_json::Value,
809    },
810    /// An error when the JSON value is not a valid enumerated discriminant.
811    #[snafu(display("Found invalid enumerated discriminant {discriminant}",))]
812    InvalidEnumDiscriminant {
813        /// The invalid enumerated discriminant.
814        discriminant: alloc::string::String,
815    },
816}
817
818impl JerDecodeErrorKind {
819    /// Helper function to create an error [JerDecodeErrorKind::EndOfInput].
820    pub fn eoi() -> CodecDecodeError {
821        CodecDecodeError::Jer(JerDecodeErrorKind::EndOfInput {})
822    }
823}
824
825// TODO check if there codec-specific errors here
826/// `DecodeError` kinds of `Kind::CodecSpecific` which are specific for UPER.
827#[derive(Snafu, Debug)]
828#[snafu(visibility(pub))]
829#[non_exhaustive]
830pub enum UperDecodeErrorKind {}
831
832// TODO check if there codec-specific errors here
833/// `DecodeError` kinds of `Kind::CodecSpecific` which are specific for APER.
834#[derive(Snafu, Debug)]
835#[snafu(visibility(pub))]
836#[non_exhaustive]
837pub enum AperDecodeErrorKind {}
838
839/// `DecodeError` kinds of `Kind::CodecSpecific` which are specific for XER.
840#[derive(Snafu, Debug)]
841#[snafu(visibility(pub))]
842#[non_exhaustive]
843pub enum XerDecodeErrorKind {
844    #[snafu(display("Unexpected end of input while decoding XER XML."))]
845    /// An error that indicates that the XML input ended unexpectedly
846    EndOfXmlInput {},
847    #[snafu(display(
848        "Found mismatching XML value. Expected type {}. Found value {}.",
849        needed,
850        found
851    ))]
852    /// An error that indicates an unexpected XML tag type or value
853    XmlTypeMismatch {
854        /// the expected tag type or value
855        needed: &'static str,
856        /// the encountered tag type or value
857        found: alloc::string::String,
858    },
859    #[snafu(display("Found invalid character in octet string."))]
860    /// An error that indicates a character in an octet string that does not conform to the hex alphabet
861    InvalidXerOctetstring {
862        /// Inner error thrown by the `parse` method
863        parse_int_err: ParseIntError,
864    },
865    #[snafu(display("Encountered invalid value. {details}"))]
866    /// An error that indicates invalid input XML
867    InvalidInput {
868        /// Error details from the underlying XML parser
869        details: &'static str,
870    },
871    #[snafu(display("Found invalid open type encoding: {inner_err}"))]
872    /// An error that indicates invalid XML in an ASN.1 open type value
873    InvalidOpenType {
874        /// Error details from the underlying XML parser
875        inner_err: xml_no_std::writer::Error,
876    },
877    #[snafu(display("XML parser error: {details}"))]
878    /// Miscellaneous error in the underlying XML parser
879    XmlParser {
880        /// Error details from the underlying XML parser
881        details: alloc::string::String,
882    },
883    #[snafu(display("Error matching tag names: expected {needed}, found {found}"))]
884    /// An error indicating an unexpected XML tag name
885    XmlTag {
886        /// The expected tag name
887        needed: alloc::string::String,
888        /// The encountered tag name
889        found: alloc::string::String,
890    },
891    #[snafu(display("Encoding violates ITU-T X.693 (02/2021): {details}"))]
892    /// An error that quotes the ITU-T X.693 paragraph being violated
893    SpecViolation {
894        /// Paragraph and excerpt from the ITU-T X.693 spec
895        details: alloc::string::String,
896    },
897}
898
899/// `DecodeError` kinds of `Kind::CodecSpecific` which are specific for OER.
900#[derive(Snafu, Debug)]
901#[snafu(visibility(pub))]
902#[non_exhaustive]
903pub enum OerDecodeErrorKind {
904    /// Tag class must be one of Universal (0b00), Application (0b01), Context (0b10) or Private (0b11).
905    #[snafu(display("Invalid tag class when decoding choice: actual {:?}", class))]
906    InvalidTagClassOnChoice {
907        /// The actual class.
908        class: u8,
909    },
910    /// The tag number was incorrect when decoding a Choice type.
911    #[snafu(display("Invalid tag number when decoding Choice. Value: {value}"))]
912    InvalidTagNumberOnChoice {
913        /// Invalid tag bytes at the time of decoding.
914        value: u32,
915    },
916    /// An error scenario where the tag number is not present in the expected Choice type.
917    #[snafu(display(
918        "Tag not found from the variants of the platform when decoding Choice. Tag: {value}, extensible status: {is_extensible}"
919    ))]
920    InvalidTagVariantOnChoice {
921        /// The tag number that was not found.
922        value: Tag,
923        /// The extensible status of the Choice type.
924        is_extensible: bool,
925    },
926
927    /// An error scenario where the extension header in preamble is invalid.
928    InvalidExtensionHeader {
929        /// The amount of invalid bits.
930        msg: alloc::string::String,
931    },
932    /// An error scenario where the BitString is invalid for some reason.
933    #[snafu(display("Invalid BitString: {msg}"))]
934    InvalidOerBitString {
935        /// The amount of invalid bits.
936        msg: alloc::string::String,
937    },
938    /// An error scenario where the preamble is invalid.
939    #[snafu(display("Invalid preamble: {msg}"))]
940    InvalidPreamble {
941        /// Message related to reason
942        msg: alloc::string::String,
943    },
944}
945
946impl OerDecodeErrorKind {
947    #[must_use]
948    /// Helper function to create an error [OerDecodeErrorKind::InvalidTagNumberOnChoice].
949    pub fn invalid_tag_number_on_choice(value: u32) -> DecodeError {
950        CodecDecodeError::Oer(Self::InvalidTagNumberOnChoice { value }).into()
951    }
952    #[must_use]
953    /// Helper function to create an error [OerDecodeErrorKind::InvalidTagVariantOnChoice].
954    pub fn invalid_tag_variant_on_choice(value: Tag, is_extensible: bool) -> DecodeError {
955        CodecDecodeError::Oer(Self::InvalidTagVariantOnChoice {
956            value,
957            is_extensible,
958        })
959        .into()
960    }
961
962    /// Helper function to create an error [OerDecodeErrorKind::InvalidExtensionHeader].
963    #[must_use]
964    pub fn invalid_extension_header(msg: alloc::string::String) -> DecodeError {
965        CodecDecodeError::Oer(Self::InvalidExtensionHeader { msg }).into()
966    }
967    /// Helper function to create an error [OerDecodeErrorKind::InvalidOerBitString].
968    #[must_use]
969    pub fn invalid_bit_string(msg: alloc::string::String) -> DecodeError {
970        CodecDecodeError::Oer(Self::InvalidOerBitString { msg }).into()
971    }
972    /// Helper function to create an error [OerDecodeErrorKind::InvalidPreamble].
973    #[must_use]
974    pub fn invalid_preamble(msg: alloc::string::String) -> DecodeError {
975        CodecDecodeError::Oer(Self::InvalidPreamble { msg }).into()
976    }
977}
978
979/// `DecodeError` kinds of `Kind::CodecSpecific` which are specific for COER.
980#[derive(Snafu, Debug)]
981#[snafu(visibility(pub))]
982#[non_exhaustive]
983pub enum CoerDecodeErrorKind {
984    /// An error of a result where the stricter Canonical Octet Encoding is not reached.
985    #[snafu(display("Invalid Canonical Octet Encoding, not encoded as the smallest possible number of octets: {msg}"))]
986    NotValidCanonicalEncoding {
987        /// Reason for the error.
988        msg: alloc::string::String,
989    },
990}
991
992impl crate::de::Error for DecodeError {
993    fn custom<D: core::fmt::Display>(msg: D, codec: Codec) -> Self {
994        Self::from_kind(
995            DecodeErrorKind::Custom {
996                msg: msg.to_string(),
997            },
998            codec,
999        )
1000    }
1001    fn incomplete(needed: nom::Needed, codec: Codec) -> Self {
1002        Self::from_kind(DecodeErrorKind::Incomplete { needed }, codec)
1003    }
1004
1005    fn exceeds_max_length(length: num_bigint::BigUint, codec: Codec) -> Self {
1006        Self::from_kind(DecodeErrorKind::ExceedsMaxLength { length }, codec)
1007    }
1008
1009    fn missing_field(name: &'static str, codec: Codec) -> Self {
1010        Self::from_kind(DecodeErrorKind::MissingField { name }, codec)
1011    }
1012
1013    fn no_valid_choice(name: &'static str, codec: Codec) -> Self {
1014        Self::from_kind(DecodeErrorKind::NoValidChoice { name }, codec)
1015    }
1016
1017    fn field_error(name: &'static str, nested: DecodeError, codec: Codec) -> Self {
1018        Self::from_kind(
1019            DecodeErrorKind::FieldError {
1020                name,
1021                nested: Box::new(nested),
1022            },
1023            codec,
1024        )
1025    }
1026
1027    fn duplicate_field(name: &'static str, codec: Codec) -> Self {
1028        Self::from_kind(DecodeErrorKind::DuplicateField { name }, codec)
1029    }
1030    fn unknown_field(index: usize, tag: Tag, codec: Codec) -> Self {
1031        Self::from_kind(DecodeErrorKind::UnknownField { index, tag }, codec)
1032    }
1033}
1034
1035#[cfg(test)]
1036mod tests {
1037    use crate::prelude::*;
1038    #[test]
1039    fn test_ber_decode_date() {
1040        use crate::error::{DecodeError, DecodeErrorKind};
1041        // "230122130000-050Z" as bytes
1042        let data = [
1043            23, 17, 50, 51, 48, 49, 50, 50, 49, 51, 48, 48, 48, 48, 45, 48, 53, 48, 90,
1044        ];
1045        let result = crate::ber::decode::<UtcTime>(&data);
1046        match result {
1047            Err(DecodeError { kind, .. }) => {
1048                if let DecodeErrorKind::CodecSpecific {
1049                    inner:
1050                        crate::error::CodecDecodeError::Ber(
1051                            crate::error::BerDecodeErrorKind::InvalidDate { msg },
1052                        ),
1053                    ..
1054                } = *kind
1055                {
1056                    assert_eq!(msg, "230122130000-050Z");
1057                } else {
1058                    // Handle other kinds of errors
1059                    panic!("Unexpected error kind: {kind}");
1060                }
1061            }
1062            Ok(_) => panic!("Expected error"),
1063        }
1064    }
1065    #[test]
1066    fn test_uper_missing_choice_index() {
1067        use crate as rasn;
1068        use crate::error::{DecodeError, DecodeErrorKind};
1069        use crate::Codec;
1070        #[derive(AsnType, Decode, Debug, PartialEq)]
1071        #[rasn(choice, automatic_tags)]
1072        enum MyChoice {
1073            Normal(Integer),
1074            High(Integer),
1075            Medium(Integer),
1076        }
1077        // Value 333 encoded for missing choice index 3
1078        let data = [192, 128, 83, 64];
1079        let result = Codec::Uper.decode_from_binary::<MyChoice>(&data);
1080        match result {
1081            Ok(_) => {
1082                panic!("Unexpected OK!");
1083            }
1084            Err(DecodeError { kind, .. }) => {
1085                if let DecodeErrorKind::ChoiceIndexNotFound { index, .. } = *kind {
1086                    assert_eq!(index, 3);
1087                } else {
1088                    // Handle other kinds of errors
1089                    panic!("Unexpected error kind: {kind}");
1090                }
1091            }
1092        }
1093    }
1094}