1#![allow(unknown_lints)]
2#![allow(non_local_definitions)] use crate::{Class, Tag};
5use alloc::str;
6use alloc::string;
7#[cfg(not(feature = "std"))]
8use alloc::string::String;
9use displaydoc::Display;
10use nom::error::{ErrorKind, FromExternalError, ParseError};
11use nom::IResult;
12#[cfg(feature = "std")]
13use std::io;
14use thiserror::Error;
15
16#[derive(Clone, Copy, Debug, Display, PartialEq, Eq, Error)]
17pub enum DerConstraint {
19 IndefiniteLength,
21 Constructed,
23 NotConstructed,
25 MissingTimeZone,
27 MissingSeconds,
29 UnusedBitsNotZero,
31 InvalidBoolean,
33 IntegerEmpty,
35 IntegerLeadingZeroes,
37 IntegerLeadingFF,
39}
40
41#[derive(Clone, Debug, Display, PartialEq, Eq, Error)]
44pub enum Error {
45 BerTypeError,
47 BerValueError,
49 InvalidLength,
51 InvalidValue { tag: Tag, msg: String },
53 InvalidTag,
55 UnknownTag(u32),
57 UnexpectedTag { expected: Option<Tag>, actual: Tag },
59 UnexpectedClass {
61 expected: Option<Class>,
62 actual: Class,
63 },
64
65 IndefiniteLengthUnexpected,
67
68 ConstructExpected,
70 ConstructUnexpected,
72
73 IntegerTooLarge,
75 IntegerNegative,
77 BerMaxDepth,
79
80 StringInvalidCharset,
82 InvalidDateTime,
84
85 DerConstraintFailed(DerConstraint),
87
88 LifetimeError,
90 Unsupported,
92
93 Incomplete(nom::Needed),
95
96 NomError(ErrorKind),
98}
99
100impl Error {
101 #[inline]
103 pub const fn invalid_value(tag: Tag, msg: String) -> Self {
104 Self::InvalidValue { tag, msg }
105 }
106
107 #[inline]
109 pub const fn unexpected_class(expected: Option<Class>, actual: Class) -> Self {
110 Self::UnexpectedClass { expected, actual }
111 }
112
113 #[inline]
115 pub const fn unexpected_tag(expected: Option<Tag>, actual: Tag) -> Self {
116 Self::UnexpectedTag { expected, actual }
117 }
118}
119
120impl<'a> ParseError<&'a [u8]> for Error {
121 fn from_error_kind(_input: &'a [u8], kind: ErrorKind) -> Self {
122 Error::NomError(kind)
123 }
124 fn append(_input: &'a [u8], kind: ErrorKind, _other: Self) -> Self {
125 Error::NomError(kind)
126 }
127}
128
129impl From<Error> for nom::Err<Error> {
130 fn from(e: Error) -> Self {
131 nom::Err::Error(e)
132 }
133}
134
135impl From<str::Utf8Error> for Error {
136 fn from(_: str::Utf8Error) -> Self {
137 Error::StringInvalidCharset
138 }
139}
140
141impl From<string::FromUtf8Error> for Error {
142 fn from(_: string::FromUtf8Error) -> Self {
143 Error::StringInvalidCharset
144 }
145}
146
147impl From<string::FromUtf16Error> for Error {
148 fn from(_: string::FromUtf16Error) -> Self {
149 Error::StringInvalidCharset
150 }
151}
152
153impl From<nom::Err<Error>> for Error {
154 fn from(e: nom::Err<Error>) -> Self {
155 match e {
156 nom::Err::Incomplete(n) => Self::Incomplete(n),
157 nom::Err::Error(e) | nom::Err::Failure(e) => e,
158 }
159 }
160}
161
162impl<I, E> FromExternalError<I, E> for Error {
163 fn from_external_error(_input: I, kind: ErrorKind, _e: E) -> Error {
164 Error::NomError(kind)
165 }
166}
167
168pub fn from_nom_error<E, F>(e: nom::Err<E>) -> F
170where
171 F: From<E> + From<Error>,
172{
173 match e {
174 nom::Err::Error(e) | nom::Err::Failure(e) => F::from(e),
175 nom::Err::Incomplete(n) => F::from(Error::Incomplete(n)),
176 }
177}
178
179pub type ParseResult<'a, T, E = Error> = IResult<&'a [u8], T, E>;
181
182pub type Result<T, E = Error> = core::result::Result<T, E>;
184
185#[cfg(feature = "std")]
187#[derive(Debug, Error)]
188pub enum SerializeError {
189 #[error("ASN.1 error: {0:?}")]
190 ASN1Error(#[from] Error),
191
192 #[error("Invalid Class {class:}")]
193 InvalidClass { class: u8 },
194
195 #[error("Invalid Length")]
196 InvalidLength,
197
198 #[error("I/O error: {0:?}")]
199 IOError(#[from] io::Error),
200}
201
202#[cfg(feature = "std")]
203pub type SerializeResult<T> = std::result::Result<T, SerializeError>;