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::de::Error;
13use crate::types::{constraints::Bounded, variants::Variants, Tag};
14use crate::Codec;
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
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
43impl_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#[derive(Debug)]
139#[allow(clippy::module_name_repetitions)]
140pub struct DecodeError {
141 pub kind: Box<DecodeErrorKind>,
143 pub codec: Codec,
145 #[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 #[must_use]
163 pub fn permitted_alphabet_error(reason: PermittedAlphabetError, codec: Codec) -> Self {
164 Self::from_kind(DecodeErrorKind::PermittedAlphabetError { reason }, codec)
165 }
166
167 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[must_use]
264 pub fn invalid_bit_string(bits: u8, codec: Codec) -> Self {
265 Self::from_kind(DecodeErrorKind::InvalidBitString { bits }, codec)
266 }
267
268 #[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 #[must_use]
283 pub fn type_not_extensible(codec: Codec) -> Self {
284 Self::from_kind(DecodeErrorKind::TypeNotExtensible, codec)
285 }
286
287 #[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 #[must_use]
295 pub fn real_not_supported(codec: Codec) -> Self {
296 DecodeError::from_kind(DecodeErrorKind::RealNotSupported, codec)
297 }
298
299 #[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 #[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 #[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 #[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 #[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 #[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 #[must_use]
353 pub fn unexpected_extra_data(length: usize, codec: Codec) -> Self {
354 Self::from_kind(DecodeErrorKind::UnexpectedExtraData { length }, codec)
355 }
356
357 #[must_use]
359 pub fn unexpected_empty_input(codec: Codec) -> Self {
360 Self::from_kind(DecodeErrorKind::UnexpectedEmptyInput, codec)
361 }
362
363 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 #[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#[derive(Snafu)]
430#[snafu(visibility(pub))]
431#[derive(Debug)]
432#[non_exhaustive]
433pub enum DecodeErrorKind {
434 #[snafu(display("Alphabet constraint not satisfied {}", reason))]
436 PermittedAlphabetError {
437 reason: PermittedAlphabetError,
439 },
440
441 #[snafu(display("Size constraint not satisfied: expected: {expected}; actual: {size:?}"))]
443 SizeConstraintNotSatisfied {
444 size: Option<usize>,
446 expected: alloc::string::String,
448 },
449
450 #[snafu(display("Value constraint not satisfied: expected: {expected}; actual: {value}"))]
452 ValueConstraintNotSatisfied {
453 value: BigInt,
455 expected: Bounded<i128>,
457 },
458 #[snafu(display("Inner subtype constraint not satisfied: {reason}"))]
460 InnerSubtypeConstraintNotSatisfied {
461 reason: super::InnerSubtypeConstraintError,
463 },
464
465 #[snafu(display("Wrapped codec-specific decode error"))]
467 CodecSpecific {
468 inner: CodecDecodeError,
470 },
471
472 #[snafu(display(
474 "Enumeration index '{}' did not match any variant. Extended list: {}",
475 index,
476 extended_list
477 ))]
478 EnumerationIndexNotFound {
479 index: usize,
481 extended_list: bool,
483 },
484
485 #[snafu(display("choice index '{index}' did not match any variant"))]
487 ChoiceIndexNotFound {
488 index: usize,
490 variants: Variants,
492 },
493
494 #[snafu(display("integer range larger than possible to address on this platform. needed: {needed} present: {present}"))]
496 ChoiceIndexExceedsPlatformWidth {
497 needed: u32,
499 present: DecodeError,
501 },
502
503 #[snafu(display("Custom: {}", msg))]
505 Custom {
506 msg: alloc::string::String,
508 },
509
510 #[snafu(display("Discriminant value '{}' did not match any variant", discriminant))]
512 DiscriminantValueNotFound {
513 discriminant: isize,
515 },
516
517 #[snafu(display("Duplicate field for `{}`", name))]
519 DuplicateField {
520 name: &'static str,
522 },
523
524 #[snafu(display("Expected maximum of {} items", length))]
526 ExceedsMaxLength {
527 length: num_bigint::BigUint,
529 },
530
531 #[snafu(display("Length of the incoming data is either exceeds platform address width."))]
533 LengthExceedsPlatformWidth {
534 msg: alloc::string::String,
536 },
537
538 #[snafu(display("Error when decoding field `{}`: {}", name, nested))]
540 FieldError {
541 name: &'static str,
543 nested: Box<DecodeError>,
545 },
546
547 #[snafu(display("Need more data to continue: ({:?}).", needed))]
551 Incomplete {
552 needed: nom::Needed,
554 },
555
556 #[snafu(display(
558 "Invalid item number in Sequence: expected {}, actual {}",
559 expected,
560 actual
561 ))]
562 IncorrectItemNumberInSequence {
563 expected: usize,
565 actual: usize,
567 },
568
569 #[snafu(display("Actual integer larger than expected {} bits", max_width))]
571 IntegerOverflow {
572 max_width: u32,
574 },
575
576 #[snafu(display("Failed to cast integer to another integer type: {msg} "))]
578 IntegerTypeConversionFailed {
579 msg: alloc::string::String,
581 },
582
583 #[snafu(display("Invalid real encoding"))]
585 InvalidRealEncoding,
586
587 #[snafu(display("Decoder doesn't support REAL types"))]
589 RealNotSupported,
590
591 #[snafu(display("BitString contains an invalid amount of unused bits: {}", bits))]
593 InvalidBitString {
594 bits: u8,
596 },
597
598 #[snafu(display(
600 "Bool value is not `0` or `0xFF` as canonical requires. Actual: {}",
601 value
602 ))]
603 InvalidBool {
604 value: u8,
606 },
607
608 #[snafu(display("Length of Length cannot be zero"))]
610 ZeroLengthOfLength,
611 #[snafu(display("Expected {:?} bytes, actual length: {:?}", expected, actual))]
613 MismatchedLength {
614 expected: usize,
616 actual: usize,
618 },
619
620 #[snafu(display("Missing field `{}`", name))]
622 MissingField {
623 name: &'static str,
625 },
626 #[snafu(display("Expected class: {}, value: {} in sequence or set Missing tag class or value in sequence or set", class, value))]
628 MissingTagClassOrValueInSequenceOrSet {
629 class: crate::types::Class,
631 value: u32,
633 },
634
635 #[snafu(display("integer range larger than possible to address on this platform. needed: {needed} present: {present}"))]
637 RangeExceedsPlatformWidth {
638 needed: u32,
640 present: u32,
642 },
643 #[snafu(display("Extension with class `{}` and tag `{}` required, but not present", tag.class, tag.value))]
645 RequiredExtensionNotPresent {
646 tag: crate::types::Tag,
648 },
649 #[snafu(display("Error in Parser: {}", msg))]
651 Parser {
652 msg: alloc::string::String,
654 },
655 #[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 tag: Tag,
664 msg: alloc::string::String,
666 },
667 #[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: Tag,
677 expected: usize,
679 actual: usize,
681 },
682 #[snafu(display("No valid choice for `{}`", name))]
684 NoValidChoice {
685 name: &'static str,
687 },
688
689 #[snafu(display("Attempted to decode extension on non-extensible type"))]
691 TypeNotExtensible,
692 #[snafu(display("Unexpected extra data found: length `{}` bytes", length))]
694 UnexpectedExtraData {
695 length: usize,
697 },
698 #[snafu(display("Unknown field with index {} and tag {}", index, tag))]
700 UnknownField {
701 index: usize,
703 tag: Tag,
705 },
706 #[snafu(display(
708 "No input was provided where expected in the given SEQUENCE or INTEGER type"
709 ))]
710 UnexpectedEmptyInput,
711}
712
713#[derive(Snafu, Debug)]
715#[snafu(visibility(pub))]
716#[non_exhaustive]
717pub enum BerDecodeErrorKind {
718 #[snafu(display("Indefinite length encountered but not allowed."))]
720 IndefiniteLengthNotAllowed,
721 #[snafu(display("Invalid constructed identifier for ASN.1 value: not primitive."))]
723 InvalidConstructedIdentifier,
724 #[snafu(display("Invalid date string: {}", msg))]
726 InvalidDate {
727 msg: alloc::string::String,
729 },
730 #[snafu(display("Invalid object identifier with missing or corrupt root nodes."))]
732 InvalidObjectIdentifier,
733 #[snafu(display("Expected {:?} tag, actual tag: {:?}", expected, actual))]
735 MismatchedTag {
736 expected: Tag,
738 actual: Tag,
740 },
741}
742
743impl BerDecodeErrorKind {
744 #[must_use]
746 pub fn invalid_date(msg: alloc::string::String) -> CodecDecodeError {
747 CodecDecodeError::Ber(Self::InvalidDate { msg })
748 }
749 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#[derive(Snafu, Debug)]
761#[snafu(visibility(pub))]
762#[non_exhaustive]
763pub enum CerDecodeErrorKind {}
764
765#[derive(Snafu, Debug)]
767#[snafu(visibility(pub))]
768#[non_exhaustive]
769pub enum DerDecodeErrorKind {
770 #[snafu(display("Constructed encoding encountered but not allowed."))]
772 ConstructedEncodingNotAllowed,
773}
774
775#[derive(Snafu, Debug)]
777#[snafu(visibility(pub))]
778#[non_exhaustive]
779pub enum JerDecodeErrorKind {
780 #[snafu(display("Unexpected end of input while decoding JER JSON."))]
782 EndOfInput {},
783 #[snafu(display(
785 "Found mismatching JSON value. Expected type {}. Found value {}.",
786 needed,
787 found
788 ))]
789 TypeMismatch {
790 needed: &'static str,
792 found: alloc::string::String,
794 },
795 #[snafu(display("Found invalid byte in bit string. {parse_int_err}"))]
797 InvalidJerBitstring {
798 parse_int_err: ParseIntError,
800 },
801 #[snafu(display("Found invalid character in octet string."))]
803 InvalidJerOctetString {},
804 #[snafu(display("Failed to construct OID from value {value}",))]
806 InvalidOIDString {
807 value: serde_json::Value,
809 },
810 #[snafu(display("Found invalid enumerated discriminant {discriminant}",))]
812 InvalidEnumDiscriminant {
813 discriminant: alloc::string::String,
815 },
816}
817
818impl JerDecodeErrorKind {
819 pub fn eoi() -> CodecDecodeError {
821 CodecDecodeError::Jer(JerDecodeErrorKind::EndOfInput {})
822 }
823}
824
825#[derive(Snafu, Debug)]
828#[snafu(visibility(pub))]
829#[non_exhaustive]
830pub enum UperDecodeErrorKind {}
831
832#[derive(Snafu, Debug)]
835#[snafu(visibility(pub))]
836#[non_exhaustive]
837pub enum AperDecodeErrorKind {}
838
839#[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 EndOfXmlInput {},
847 #[snafu(display(
848 "Found mismatching XML value. Expected type {}. Found value {}.",
849 needed,
850 found
851 ))]
852 XmlTypeMismatch {
854 needed: &'static str,
856 found: alloc::string::String,
858 },
859 #[snafu(display("Found invalid character in octet string."))]
860 InvalidXerOctetstring {
862 parse_int_err: ParseIntError,
864 },
865 #[snafu(display("Encountered invalid value. {details}"))]
866 InvalidInput {
868 details: &'static str,
870 },
871 #[snafu(display("Found invalid open type encoding: {inner_err}"))]
872 InvalidOpenType {
874 inner_err: xml_no_std::writer::Error,
876 },
877 #[snafu(display("XML parser error: {details}"))]
878 XmlParser {
880 details: alloc::string::String,
882 },
883 #[snafu(display("Error matching tag names: expected {needed}, found {found}"))]
884 XmlTag {
886 needed: alloc::string::String,
888 found: alloc::string::String,
890 },
891 #[snafu(display("Encoding violates ITU-T X.693 (02/2021): {details}"))]
892 SpecViolation {
894 details: alloc::string::String,
896 },
897}
898
899#[derive(Snafu, Debug)]
901#[snafu(visibility(pub))]
902#[non_exhaustive]
903pub enum OerDecodeErrorKind {
904 #[snafu(display("Invalid tag class when decoding choice: actual {:?}", class))]
906 InvalidTagClassOnChoice {
907 class: u8,
909 },
910 #[snafu(display("Invalid tag number when decoding Choice. Value: {value}"))]
912 InvalidTagNumberOnChoice {
913 value: u32,
915 },
916 #[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 value: Tag,
923 is_extensible: bool,
925 },
926
927 InvalidExtensionHeader {
929 msg: alloc::string::String,
931 },
932 #[snafu(display("Invalid BitString: {msg}"))]
934 InvalidOerBitString {
935 msg: alloc::string::String,
937 },
938 #[snafu(display("Invalid preamble: {msg}"))]
940 InvalidPreamble {
941 msg: alloc::string::String,
943 },
944}
945
946impl OerDecodeErrorKind {
947 #[must_use]
948 pub fn invalid_tag_number_on_choice(value: u32) -> DecodeError {
950 CodecDecodeError::Oer(Self::InvalidTagNumberOnChoice { value }).into()
951 }
952 #[must_use]
953 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 #[must_use]
964 pub fn invalid_extension_header(msg: alloc::string::String) -> DecodeError {
965 CodecDecodeError::Oer(Self::InvalidExtensionHeader { msg }).into()
966 }
967 #[must_use]
969 pub fn invalid_bit_string(msg: alloc::string::String) -> DecodeError {
970 CodecDecodeError::Oer(Self::InvalidOerBitString { msg }).into()
971 }
972 #[must_use]
974 pub fn invalid_preamble(msg: alloc::string::String) -> DecodeError {
975 CodecDecodeError::Oer(Self::InvalidPreamble { msg }).into()
976 }
977}
978
979#[derive(Snafu, Debug)]
981#[snafu(visibility(pub))]
982#[non_exhaustive]
983pub enum CoerDecodeErrorKind {
984 #[snafu(display("Invalid Canonical Octet Encoding, not encoded as the smallest possible number of octets: {msg}"))]
986 NotValidCanonicalEncoding {
987 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 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 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 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 panic!("Unexpected error kind: {kind}");
1090 }
1091 }
1092 }
1093 }
1094}