1use crate::Salt;
4use base64ct::Error as B64Error;
5use core::{cmp::Ordering, fmt};
6
7pub type Result<T> = core::result::Result<T, Error>;
9
10#[derive(Copy, Clone, Debug, Eq, PartialEq)]
12#[non_exhaustive]
13pub enum Error {
14 Base64(B64Error),
16
17 MissingField,
19
20 OutputSize {
22 provided: Ordering,
28
29 expected: usize,
35 },
36
37 ParamNameDuplicated,
39
40 ParamNameInvalid,
42
43 ParamValueInvalid,
45
46 ParamValueTooLong,
48
49 ParamsMaxExceeded,
51
52 SaltTooShort,
54
55 SaltTooLong,
57
58 TrailingData,
60
61 ValueTooLong,
63}
64
65impl fmt::Display for Error {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::result::Result<(), fmt::Error> {
67 match self {
68 Self::Base64(err) => write!(f, "{err}"),
69 Self::MissingField => write!(f, "password hash string missing field"),
70 Self::OutputSize { provided, expected } => match provided {
71 Ordering::Less => write!(
72 f,
73 "output size too short, expected at least {expected} bytes",
74 ),
75 Ordering::Equal => write!(f, "output size unexpected, expected {expected} bytes"),
76 Ordering::Greater => {
77 write!(f, "output size too long, expected at most {expected} bytes")
78 }
79 },
80 Self::ParamNameDuplicated => write!(f, "duplicate parameter"),
81 Self::ParamNameInvalid => write!(f, "invalid parameter name"),
82 Self::ParamValueInvalid => write!(f, "invalid parameter value"),
83 Self::ParamValueTooLong => write!(f, "parameter value too long"),
84 Self::ParamsMaxExceeded => write!(f, "maximum number of parameters reached"),
85 Self::SaltTooShort => write!(f, "salt too short (minimum {} bytes)", Salt::MIN_LENGTH),
86 Self::SaltTooLong => write!(f, "salt too long (maximum {} bytes)", Salt::MAX_LENGTH),
87 Self::TrailingData => write!(f, "password hash has unexpected trailing characters"),
88 Self::ValueTooLong => f.write_str("value too long"),
89 }
90 }
91}
92
93impl core::error::Error for Error {
94 fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
95 match self {
96 Self::Base64(err) => Some(err),
97 _ => None,
98 }
99 }
100}
101
102impl From<B64Error> for Error {
103 fn from(err: B64Error) -> Error {
104 Error::Base64(err)
105 }
106}
107
108impl From<base64ct::InvalidLengthError> for Error {
109 fn from(_: base64ct::InvalidLengthError) -> Error {
110 Error::Base64(B64Error::InvalidLength)
111 }
112}