1use core::fmt;
4
5pub type Result<T> = core::result::Result<T, Error>;
7
8#[derive(Copy, Clone, Debug, Eq, PartialEq)]
10#[non_exhaustive]
11pub enum Error {
12 Base64(base64ct::Error),
14
15 CharacterEncoding,
17
18 EncapsulatedText,
20
21 HeaderDisallowed,
23
24 Label,
26
27 Length,
29
30 Preamble,
32
33 PreEncapsulationBoundary,
35
36 PostEncapsulationBoundary,
38
39 UnexpectedTypeLabel {
41 expected: &'static str,
43 },
44}
45
46impl fmt::Display for Error {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 match *self {
49 Error::Base64(err) => write!(f, "PEM Base64 error: {err}"),
50 Error::CharacterEncoding => f.write_str("PEM character encoding error"),
51 Error::EncapsulatedText => f.write_str("PEM error in encapsulated text"),
52 Error::HeaderDisallowed => f.write_str("PEM headers disallowed by RFC7468"),
53 Error::Label => f.write_str("PEM type label invalid"),
54 Error::Length => f.write_str("PEM length invalid"),
55 Error::Preamble => f.write_str("PEM preamble contains invalid data (NUL byte)"),
56 Error::PreEncapsulationBoundary => {
57 f.write_str("PEM error in pre-encapsulation boundary")
58 }
59 Error::PostEncapsulationBoundary => {
60 f.write_str("PEM error in post-encapsulation boundary")
61 }
62 Error::UnexpectedTypeLabel { expected } => {
63 write!(
64 f,
65 "unexpected PEM type label: expecting \"BEGIN {expected}\""
66 )
67 }
68 }
69 }
70}
71
72impl core::error::Error for Error {}
73
74impl From<base64ct::Error> for Error {
75 fn from(err: base64ct::Error) -> Error {
76 Error::Base64(err)
77 }
78}
79
80impl From<base64ct::InvalidLengthError> for Error {
81 fn from(_: base64ct::InvalidLengthError) -> Error {
82 Error::Length
83 }
84}
85
86impl From<core::str::Utf8Error> for Error {
87 fn from(_: core::str::Utf8Error) -> Error {
88 Error::CharacterEncoding
89 }
90}
91
92#[cfg(feature = "std")]
93impl From<Error> for std::io::Error {
94 fn from(err: Error) -> std::io::Error {
95 let kind = match err {
96 Error::Base64(err) => return err.into(), Error::CharacterEncoding
98 | Error::EncapsulatedText
99 | Error::Label
100 | Error::Preamble
101 | Error::PreEncapsulationBoundary
102 | Error::PostEncapsulationBoundary => std::io::ErrorKind::InvalidData,
103 Error::Length => std::io::ErrorKind::UnexpectedEof,
104 _ => std::io::ErrorKind::Other,
105 };
106
107 std::io::Error::new(kind, err)
108 }
109}