1use crate::{Class, Tag};
2use alloc::str;
3use alloc::string;
4use alloc::string::String;
5use displaydoc::Display;
6use nom::error::{ErrorKind, FromExternalError, ParseError};
7use nom::IResult;
8#[cfg(feature = "std")]
9use std::io;
10#[cfg(feature = "std")]
11use thiserror::Error;
12
13#[cfg(feature = "std")]
14impl std::error::Error for DerConstraint {}
15
16#[derive(Clone, Copy, Debug, Display, PartialEq, Eq)]
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#[cfg(feature = "std")]
46impl std::error::Error for Error {}
47
48#[derive(Clone, Debug, Display, PartialEq, Eq)]
51pub enum Error {
53 BerTypeError,
55 BerValueError,
57 InvalidLength,
59 InvalidValue { tag: Tag, msg: String },
61 InvalidTag,
63 UnknownTag(u32),
65 UnexpectedTag { expected: Option<Tag>, actual: Tag },
67 UnexpectedClass {
69 expected: Option<Class>,
70 actual: Class,
71 },
72
73 IndefiniteLengthUnexpected,
75
76 ConstructExpected,
78 ConstructUnexpected,
80
81 IntegerTooLarge,
83 IntegerNegative,
85 BerMaxDepth,
87
88 StringInvalidCharset,
90 InvalidDateTime,
92
93 DerConstraintFailed(DerConstraint),
95
96 LifetimeError,
98 Unsupported,
100
101 Incomplete(nom::Needed),
103
104 NomError(ErrorKind),
106}
107
108impl Error {
109 #[inline]
111 pub const fn invalid_value(tag: Tag, msg: String) -> Self {
112 Self::InvalidValue { tag, msg }
113 }
114
115 #[inline]
117 pub const fn unexpected_class(expected: Option<Class>, actual: Class) -> Self {
118 Self::UnexpectedClass { expected, actual }
119 }
120
121 #[inline]
123 pub const fn unexpected_tag(expected: Option<Tag>, actual: Tag) -> Self {
124 Self::UnexpectedTag { expected, actual }
125 }
126}
127
128impl<'a> ParseError<&'a [u8]> for Error {
129 fn from_error_kind(_input: &'a [u8], kind: ErrorKind) -> Self {
130 Error::NomError(kind)
131 }
132 fn append(_input: &'a [u8], kind: ErrorKind, _other: Self) -> Self {
133 Error::NomError(kind)
134 }
135}
136
137impl From<Error> for nom::Err<Error> {
138 fn from(e: Error) -> Self {
139 nom::Err::Error(e)
140 }
141}
142
143impl From<str::Utf8Error> for Error {
144 fn from(_: str::Utf8Error) -> Self {
145 Error::StringInvalidCharset
146 }
147}
148
149impl From<string::FromUtf8Error> for Error {
150 fn from(_: string::FromUtf8Error) -> Self {
151 Error::StringInvalidCharset
152 }
153}
154
155impl From<string::FromUtf16Error> for Error {
156 fn from(_: string::FromUtf16Error) -> Self {
157 Error::StringInvalidCharset
158 }
159}
160
161impl From<nom::Err<Error>> for Error {
162 fn from(e: nom::Err<Error>) -> Self {
163 match e {
164 nom::Err::Incomplete(n) => Self::Incomplete(n),
165 nom::Err::Error(e) | nom::Err::Failure(e) => e,
166 }
167 }
168}
169
170impl<I, E> FromExternalError<I, E> for Error {
171 fn from_external_error(_input: I, kind: ErrorKind, _e: E) -> Error {
172 Error::NomError(kind)
173 }
174}
175
176pub type ParseResult<'a, T, E = Error> = IResult<&'a [u8], T, E>;
178
179pub type Result<T, E = Error> = core::result::Result<T, E>;
181
182#[cfg(feature = "std")]
184#[derive(Debug, Error)]
185pub enum SerializeError {
186 #[error("ASN.1 error: {0:?}")]
187 ASN1Error(#[from] Error),
188
189 #[error("Invalid Class {class:}")]
190 InvalidClass { class: u8 },
191
192 #[error("Invalid Length")]
193 InvalidLength,
194
195 #[error("I/O error: {0:?}")]
196 IOError(#[from] io::Error),
197}
198
199#[cfg(feature = "std")]
200pub type SerializeResult<T> = std::result::Result<T, SerializeError>;