bitcoin_internals/error/
input_string.rs1use core::fmt;
4
5use storage::Storage;
6
7#[derive(Debug, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
15pub struct InputString(Storage);
16
17impl InputString {
18 pub fn display_cannot_parse<'a, T>(&'a self, what: &'a T) -> CannotParse<'a, T>
22 where
23 T: fmt::Display + ?Sized,
24 {
25 CannotParse { input: self, what }
26 }
27
28 pub fn unknown_variant<T>(&self, what: &T, f: &mut fmt::Formatter) -> fmt::Result
32 where
33 T: fmt::Display + ?Sized,
34 {
35 storage::unknown_variant(&self.0, what, f)
36 }
37}
38
39macro_rules! impl_from {
40 ($($type:ty),+ $(,)?) => {
41 $(
42 impl From<$type> for InputString {
43 fn from(input: $type) -> Self {
44 #[allow(clippy::useless_conversion)]
45 InputString(input.into())
46 }
47 }
48 )+
49 }
50}
51
52impl_from!(&str);
53
54pub struct CannotParse<'a, T: fmt::Display + ?Sized> {
61 input: &'a InputString,
62 what: &'a T,
63}
64
65impl<'a, T: fmt::Display + ?Sized> fmt::Display for CannotParse<'a, T> {
66 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67 storage::cannot_parse(&self.input.0, &self.what, f)
68 }
69}
70
71#[cfg(not(feature = "alloc"))]
72mod storage {
73 use core::fmt;
74
75 #[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
76 pub(super) struct Storage;
77
78 impl fmt::Debug for Storage {
79 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80 f.write_str("<unknown input string - compiled without the `alloc` feature>")
81 }
82 }
83
84 impl From<&str> for Storage {
85 fn from(_value: &str) -> Self { Storage }
86 }
87
88 pub(super) fn cannot_parse<W>(_: &Storage, what: &W, f: &mut fmt::Formatter) -> fmt::Result
89 where
90 W: fmt::Display + ?Sized,
91 {
92 write!(f, "failed to parse {}", what)
93 }
94
95 pub(super) fn unknown_variant<W>(_: &Storage, what: &W, f: &mut fmt::Formatter) -> fmt::Result
96 where
97 W: fmt::Display + ?Sized,
98 {
99 write!(f, "unknown {}", what)
100 }
101}
102
103#[cfg(feature = "alloc")]
104mod storage {
105 use core::fmt;
106
107 use super::InputString;
108
109 pub(super) type Storage = alloc::string::String;
110
111 pub(super) fn cannot_parse<W>(input: &Storage, what: &W, f: &mut fmt::Formatter) -> fmt::Result
112 where
113 W: fmt::Display + ?Sized,
114 {
115 write!(f, "failed to parse '{}' as {}", input, what)
116 }
117
118 pub(super) fn unknown_variant<W>(inp: &Storage, what: &W, f: &mut fmt::Formatter) -> fmt::Result
119 where
120 W: fmt::Display + ?Sized,
121 {
122 write!(f, "'{}' is not a known {}", inp, what)
123 }
124
125 impl_from!(alloc::string::String, alloc::boxed::Box<str>, alloc::borrow::Cow<'_, str>);
126}