1use core::fmt;
4
5use internals::write_err;
6
7use crate::address::{Address, NetworkUnchecked};
8use crate::blockdata::script::{witness_program, witness_version};
9use crate::prelude::*;
10use crate::Network;
11
12#[derive(Debug, Clone, PartialEq, Eq)]
14#[non_exhaustive]
15pub enum FromScriptError {
16 UnrecognizedScript,
18 WitnessProgram(witness_program::Error),
20 WitnessVersion(witness_version::TryFromError),
22}
23
24internals::impl_from_infallible!(FromScriptError);
25
26impl fmt::Display for FromScriptError {
27 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28 use FromScriptError::*;
29
30 match *self {
31 WitnessVersion(ref e) => write_err!(f, "witness version construction error"; e),
32 WitnessProgram(ref e) => write_err!(f, "witness program error"; e),
33 UnrecognizedScript => write!(f, "script is not a p2pkh, p2sh or witness program"),
34 }
35 }
36}
37
38#[cfg(feature = "std")]
39impl std::error::Error for FromScriptError {
40 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
41 use FromScriptError::*;
42
43 match *self {
44 UnrecognizedScript => None,
45 WitnessVersion(ref e) => Some(e),
46 WitnessProgram(ref e) => Some(e),
47 }
48 }
49}
50
51impl From<witness_program::Error> for FromScriptError {
52 fn from(e: witness_program::Error) -> Self { Self::WitnessProgram(e) }
53}
54
55impl From<witness_version::TryFromError> for FromScriptError {
56 fn from(e: witness_version::TryFromError) -> Self { Self::WitnessVersion(e) }
57}
58
59#[derive(Debug, Clone, PartialEq, Eq)]
61#[non_exhaustive]
62pub enum P2shError {
63 ExcessiveScriptSize,
65}
66
67internals::impl_from_infallible!(P2shError);
68
69impl fmt::Display for P2shError {
70 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
71 use P2shError::*;
72
73 match *self {
74 ExcessiveScriptSize => write!(f, "script size exceed 520 bytes"),
75 }
76 }
77}
78
79#[cfg(feature = "std")]
80impl std::error::Error for P2shError {
81 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
82 use P2shError::*;
83
84 match self {
85 ExcessiveScriptSize => None,
86 }
87 }
88}
89
90#[derive(Debug, Clone, PartialEq, Eq)]
92#[non_exhaustive]
93pub struct UnknownAddressTypeError(pub String);
94
95impl fmt::Display for UnknownAddressTypeError {
96 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97 write_err!(f, "failed to parse {} as address type", self.0; self)
98 }
99}
100
101#[cfg(feature = "std")]
102impl std::error::Error for UnknownAddressTypeError {
103 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
104}
105
106#[derive(Debug, Clone, PartialEq, Eq)]
108#[non_exhaustive]
109pub enum ParseError {
110 Base58(base58::Error),
112 Bech32(bech32::segwit::DecodeError),
114 WitnessVersion(witness_version::TryFromError),
116 WitnessProgram(witness_program::Error),
118 UnknownHrp(UnknownHrpError),
120 LegacyAddressTooLong(LegacyAddressTooLongError),
122 InvalidBase58PayloadLength(InvalidBase58PayloadLengthError),
124 InvalidLegacyPrefix(InvalidLegacyPrefixError),
126 NetworkValidation(NetworkValidationError),
128}
129
130internals::impl_from_infallible!(ParseError);
131
132impl fmt::Display for ParseError {
133 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
134 use ParseError::*;
135
136 match *self {
137 Base58(ref e) => write_err!(f, "base58 error"; e),
138 Bech32(ref e) => write_err!(f, "bech32 segwit decoding error"; e),
139 WitnessVersion(ref e) => write_err!(f, "witness version conversion/parsing error"; e),
140 WitnessProgram(ref e) => write_err!(f, "witness program error"; e),
141 UnknownHrp(ref e) => write_err!(f, "tried to parse an unknown hrp"; e),
142 LegacyAddressTooLong(ref e) => write_err!(f, "legacy address base58 string"; e),
143 InvalidBase58PayloadLength(ref e) => write_err!(f, "legacy address base58 data"; e),
144 InvalidLegacyPrefix(ref e) => write_err!(f, "legacy address base58 prefix"; e),
145 NetworkValidation(ref e) => write_err!(f, "validation error"; e),
146 }
147 }
148}
149
150#[cfg(feature = "std")]
151impl std::error::Error for ParseError {
152 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
153 use ParseError::*;
154
155 match *self {
156 Base58(ref e) => Some(e),
157 Bech32(ref e) => Some(e),
158 WitnessVersion(ref e) => Some(e),
159 WitnessProgram(ref e) => Some(e),
160 UnknownHrp(ref e) => Some(e),
161 LegacyAddressTooLong(ref e) => Some(e),
162 InvalidBase58PayloadLength(ref e) => Some(e),
163 InvalidLegacyPrefix(ref e) => Some(e),
164 NetworkValidation(ref e) => Some(e),
165 }
166 }
167}
168
169impl From<base58::Error> for ParseError {
170 fn from(e: base58::Error) -> Self { Self::Base58(e) }
171}
172
173impl From<bech32::segwit::DecodeError> for ParseError {
174 fn from(e: bech32::segwit::DecodeError) -> Self { Self::Bech32(e) }
175}
176
177impl From<witness_version::TryFromError> for ParseError {
178 fn from(e: witness_version::TryFromError) -> Self { Self::WitnessVersion(e) }
179}
180
181impl From<witness_program::Error> for ParseError {
182 fn from(e: witness_program::Error) -> Self { Self::WitnessProgram(e) }
183}
184
185impl From<UnknownHrpError> for ParseError {
186 fn from(e: UnknownHrpError) -> Self { Self::UnknownHrp(e) }
187}
188
189impl From<LegacyAddressTooLongError> for ParseError {
190 fn from(e: LegacyAddressTooLongError) -> Self { Self::LegacyAddressTooLong(e) }
191}
192
193impl From<InvalidBase58PayloadLengthError> for ParseError {
194 fn from(e: InvalidBase58PayloadLengthError) -> Self { Self::InvalidBase58PayloadLength(e) }
195}
196
197impl From<InvalidLegacyPrefixError> for ParseError {
198 fn from(e: InvalidLegacyPrefixError) -> Self { Self::InvalidLegacyPrefix(e) }
199}
200
201impl From<NetworkValidationError> for ParseError {
202 fn from(e: NetworkValidationError) -> Self { Self::NetworkValidation(e) }
203}
204
205#[derive(Debug, Clone, PartialEq, Eq)]
207#[non_exhaustive]
208pub struct UnknownHrpError(pub String);
209
210impl fmt::Display for UnknownHrpError {
211 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "unknown hrp: {}", self.0) }
212}
213
214#[cfg(feature = "std")]
215impl std::error::Error for UnknownHrpError {
216 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
217}
218
219#[derive(Debug, Clone, PartialEq, Eq)]
221pub struct NetworkValidationError {
222 pub(crate) required: Network,
224 pub(crate) address: Address<NetworkUnchecked>,
226}
227
228impl fmt::Display for NetworkValidationError {
229 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
230 write!(f, "address ")?;
231 fmt::Display::fmt(&self.address.0, f)?;
232 write!(f, " is not valid on {}", self.required)
233 }
234}
235
236#[cfg(feature = "std")]
237impl std::error::Error for NetworkValidationError {}
238
239#[derive(Debug, Clone, PartialEq, Eq)]
241pub struct InvalidBase58PayloadLengthError {
242 pub(crate) length: usize,
244}
245
246impl InvalidBase58PayloadLengthError {
247 pub fn invalid_base58_payload_length(&self) -> usize { self.length }
249}
250
251impl fmt::Display for InvalidBase58PayloadLengthError {
252 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
253 write!(f, "decoded base58 data was an invalid length: {} (expected 21)", self.length)
254 }
255}
256
257#[cfg(feature = "std")]
258impl std::error::Error for InvalidBase58PayloadLengthError {}
259
260#[derive(Debug, Clone, PartialEq, Eq)]
262pub struct LegacyAddressTooLongError {
263 pub(crate) length: usize,
265}
266
267impl LegacyAddressTooLongError {
268 pub fn invalid_legcay_address_length(&self) -> usize { self.length }
270}
271
272impl fmt::Display for LegacyAddressTooLongError {
273 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
274 write!(f, "legacy address is too long: {} (max 50 characters)", self.length)
275 }
276}
277
278#[cfg(feature = "std")]
279impl std::error::Error for LegacyAddressTooLongError {}
280
281#[derive(Debug, Clone, PartialEq, Eq)]
283pub struct InvalidLegacyPrefixError {
284 pub(crate) invalid: u8,
286}
287
288impl InvalidLegacyPrefixError {
289 pub fn invalid_legacy_address_prefix(&self) -> u8 { self.invalid }
291}
292
293impl fmt::Display for InvalidLegacyPrefixError {
294 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
295 write!(f, "invalid legacy address prefix in decoded base58 data {}", self.invalid)
296 }
297}
298
299#[cfg(feature = "std")]
300impl std::error::Error for InvalidLegacyPrefixError {}