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;
14#[cfg(feature = "std")]
15use thiserror::Error;
16
17#[cfg(feature = "std")]
18impl std::error::Error for DerConstraint {}
19
20#[derive(Clone, Copy, Debug, Display, PartialEq, Eq)]
21pub enum DerConstraint {
23 IndefiniteLength,
25 Constructed,
27 NotConstructed,
29 MissingTimeZone,
31 MissingSeconds,
33 UnusedBitsNotZero,
35 InvalidBoolean,
37 IntegerEmpty,
39 IntegerLeadingZeroes,
41 IntegerLeadingFF,
43}
44
45#[cfg(feature = "std")]
50impl std::error::Error for Error {}
51
52#[derive(Clone, Debug, Display, PartialEq, Eq)]
55pub enum Error {
57 BerTypeError,
59 BerValueError,
61 InvalidLength,
63 InvalidValue { tag: Tag, msg: String },
65 InvalidTag,
67 UnknownTag(u32),
69 UnexpectedTag { expected: Option<Tag>, actual: Tag },
71 UnexpectedClass {
73 expected: Option<Class>,
74 actual: Class,
75 },
76
77 IndefiniteLengthUnexpected,
79
80 ConstructExpected,
82 ConstructUnexpected,
84
85 IntegerTooLarge,
87 IntegerNegative,
89 BerMaxDepth,
91
92 StringInvalidCharset,
94 InvalidDateTime,
96
97 DerConstraintFailed(DerConstraint),
99
100 LifetimeError,
102 Unsupported,
104
105 Incomplete(nom::Needed),
107
108 NomError(ErrorKind),
110}
111
112impl Error {
113 #[inline]
115 pub const fn invalid_value(tag: Tag, msg: String) -> Self {
116 Self::InvalidValue { tag, msg }
117 }
118
119 #[inline]
121 pub const fn unexpected_class(expected: Option<Class>, actual: Class) -> Self {
122 Self::UnexpectedClass { expected, actual }
123 }
124
125 #[inline]
127 pub const fn unexpected_tag(expected: Option<Tag>, actual: Tag) -> Self {
128 Self::UnexpectedTag { expected, actual }
129 }
130}
131
132impl<'a> ParseError<&'a [u8]> for Error {
133 fn from_error_kind(_input: &'a [u8], kind: ErrorKind) -> Self {
134 Error::NomError(kind)
135 }
136 fn append(_input: &'a [u8], kind: ErrorKind, _other: Self) -> Self {
137 Error::NomError(kind)
138 }
139}
140
141impl From<Error> for nom::Err<Error> {
142 fn from(e: Error) -> Self {
143 nom::Err::Error(e)
144 }
145}
146
147impl From<str::Utf8Error> for Error {
148 fn from(_: str::Utf8Error) -> Self {
149 Error::StringInvalidCharset
150 }
151}
152
153impl From<string::FromUtf8Error> for Error {
154 fn from(_: string::FromUtf8Error) -> Self {
155 Error::StringInvalidCharset
156 }
157}
158
159impl From<string::FromUtf16Error> for Error {
160 fn from(_: string::FromUtf16Error) -> Self {
161 Error::StringInvalidCharset
162 }
163}
164
165impl From<nom::Err<Error>> for Error {
166 fn from(e: nom::Err<Error>) -> Self {
167 match e {
168 nom::Err::Incomplete(n) => Self::Incomplete(n),
169 nom::Err::Error(e) | nom::Err::Failure(e) => e,
170 }
171 }
172}
173
174impl<I, E> FromExternalError<I, E> for Error {
175 fn from_external_error(_input: I, kind: ErrorKind, _e: E) -> Error {
176 Error::NomError(kind)
177 }
178}
179
180pub fn from_nom_error<E, F>(e: nom::Err<E>) -> F
182where
183 F: From<E> + From<Error>,
184{
185 match e {
186 nom::Err::Error(e) | nom::Err::Failure(e) => F::from(e),
187 nom::Err::Incomplete(n) => F::from(Error::Incomplete(n)),
188 }
189}
190
191pub type ParseResult<'a, T, E = Error> = IResult<&'a [u8], T, E>;
193
194pub type Result<T, E = Error> = core::result::Result<T, E>;
196
197#[cfg(feature = "std")]
199#[derive(Debug, Error)]
200pub enum SerializeError {
201 #[error("ASN.1 error: {0:?}")]
202 ASN1Error(#[from] Error),
203
204 #[error("Invalid Class {class:}")]
205 InvalidClass { class: u8 },
206
207 #[error("Invalid Length")]
208 InvalidLength,
209
210 #[error("I/O error: {0:?}")]
211 IOError(#[from] io::Error),
212}
213
214#[cfg(feature = "std")]
215pub type SerializeResult<T> = std::result::Result<T, SerializeError>;