1use super::consts::AddressType;
9
10use std::{error::Error, fmt};
11
12#[derive(Debug, PartialEq, Eq, Clone)]
14pub enum EncodingError {
15 InvalidAddressType(u8),
16 InvalidLength(usize),
17 InvalidNetworkId(u64),
18}
19
20impl fmt::Display for EncodingError {
21 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22 match self {
23 Self::InvalidAddressType(type_byte) => {
24 write!(f, "unrecognized type bits 0x{:02x}", type_byte)
25 }
26 Self::InvalidLength(length) => {
27 write!(f, "invalid length ({})", length)
28 }
29 Self::InvalidNetworkId(network_id) => {
30 write!(f, "invalid network_id (reserved: {})", network_id)
31 }
32 }
33 }
34}
35
36impl Error for EncodingError {
37 fn cause(&self) -> Option<&dyn Error> { None }
38
39 fn description(&self) -> &str { "invalid length" }
40}
41
42#[derive(Debug, PartialEq, Eq, Clone)]
44pub enum DecodingError {
45 InvalidLength(usize),
47 NoPrefix,
49 InvalidPrefix(String),
51 InvalidOption(OptionError),
53 ChecksumFailed(u64),
55 InvalidChar(char),
57 InvalidPadding {
60 from_bits: u8,
61 padding_bits: u8,
62 padding: u16,
63 },
64 VersionNotRecognized(u8),
66 MixedCase,
68}
69
70#[derive(Debug, PartialEq, Eq, Clone)]
71pub enum OptionError {
72 ParseError(String),
74 AddressTypeMismatch {
78 expected: AddressType,
79 got: Result<AddressType, ()>,
80 },
81 InvalidAddressType(String),
83}
84
85impl fmt::Display for DecodingError {
86 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
87 match self {
88 DecodingError::ChecksumFailed(actual) => {
89 write!(f, "invalid checksum (actual {} != 0)", actual)
90 }
91 DecodingError::InvalidChar(index) => {
92 write!(f, "invalid char ({})", index)
93 }
94 DecodingError::InvalidLength(length) => {
95 write!(f, "invalid length ({})", length)
96 }
97 DecodingError::InvalidPadding {
98 from_bits,
99 padding_bits,
100 padding,
101 } => {
102 write!(f, "invalid padding (")?;
103 if padding_bits >= from_bits {
104 write!(
105 f,
106 "padding_bits({}) >= from_bits({})",
107 padding_bits, from_bits
108 )?;
109 if *padding != 0 {
110 write!(f, ", padding({:#b}) is non-zero)", padding)?;
111 }
112 } else {
113 write!(f, "padding({:#b}) is non-zero)", padding)?;
114 }
115 Ok(())
116 }
117 DecodingError::InvalidPrefix(prefix) => {
118 write!(f, "invalid prefix ({})", prefix)
119 }
120 DecodingError::InvalidOption(option_error) => match option_error {
121 OptionError::AddressTypeMismatch { expected, got } => {
122 write!(f, "expected address type specified in option {:?}, decoded address type {:?}", expected, got)
123 }
124 OptionError::ParseError(option_str) => {
125 write!(f, "invalid option string ({})", option_str)
126 }
127 OptionError::InvalidAddressType(type_str) => {
128 write!(f, "invalid address type ({})", type_str)
129 }
130 },
131 DecodingError::NoPrefix => write!(f, "zero or multiple prefixes"),
132 DecodingError::MixedCase => write!(f, "mixed case string"),
133 DecodingError::VersionNotRecognized(c) => {
134 write!(f, "version byte ({}) not recognized", c)
135 }
136 }
137 }
138}
139
140impl Error for DecodingError {
141 fn cause(&self) -> Option<&dyn Error> { None }
142
143 fn description(&self) -> &str {
144 match self {
145 DecodingError::ChecksumFailed { .. } => "invalid checksum",
146 DecodingError::InvalidChar(_) => "invalid char",
147 DecodingError::InvalidLength(_) => "invalid length",
148 DecodingError::InvalidOption(option_error) => match option_error {
149 OptionError::AddressTypeMismatch { .. } => {
150 "decoded address does not match address type in option"
151 }
152 OptionError::ParseError(_) => "invalid option",
153 OptionError::InvalidAddressType(_) => "invalid address type",
154 },
155 DecodingError::InvalidPadding { .. } => "invalid padding",
156 DecodingError::InvalidPrefix(_) => "invalid prefix",
157 DecodingError::NoPrefix => "zero or multiple prefixes",
158 DecodingError::MixedCase => "mixed case string",
159 DecodingError::VersionNotRecognized(_) => {
160 "version byte not recognized"
161 }
162 }
163 }
164}