bitcoin_internals/
parse.rs1#[doc(hidden)]
5#[macro_export]
6macro_rules! impl_try_from_stringly {
7 ($from:ty, $to:ty, $error:ty, $func:expr) => {
8 $(#[$attr])?
9 impl core::convert::TryFrom<$from> for $to {
10 type Error = $error;
11
12 fn try_from(s: $from) -> core::result::Result<Self, Self::Error> {
13 $func(AsRef::<str>::as_ref(s)).map_err(|source| <$error>::new(s, source))
14 }
15 }
16
17 }
18}
19
20#[macro_export]
32macro_rules! impl_parse {
33 ($type:ty, $descr:expr, $func:expr, $vis:vis $error:ident, $error_source:ty $(, $error_derive:path)*) => {
34 $crate::parse_error_type!($vis $error, $error_source, $descr $(, $error_derive)*);
35
36 impl core::str::FromStr for $type {
37 type Err = $error;
38
39 fn from_str(s: &str) -> core::result::Result<Self, Self::Err> {
40 $func(s).map_err(|source| <$error>::new(s, source))
41 }
42 }
43
44 impl_try_from_stringly!(&str);
45
46 #[cfg(feature = "alloc")]
47 impl_try_from_stringly!(alloc::string::String, $type, $error, $func);
48 #[cfg(feature = "alloc")]
49 impl_try_from_stringly!(alloc::borrow::Cow<'_, str>, $type, $error, $func);
50 #[cfg(feature = "alloc")]
51 impl_try_from_stringly!(alloc::boxed::Box<str>, $type, $error, $func);
52 }
53}
54
55#[macro_export]
60macro_rules! impl_parse_and_serde {
61 ($type:ty, $descr:expr, $func:expr, $error:ident, $error_source:ty $(, $error_derive:path)*) => {
62 impl_parse!($type, $descr, $func, $error, $error_source $(, $error_derive)*);
63
64 #[cfg(feature = "serde")]
66 impl<'de> $crate::serde::Deserialize<'de> for $type {
67 fn deserialize<D>(deserializer: D) -> core::result::Result<$name, D::Error>
68 where
69 D: $crate::serde::de::Deserializer<'de>,
70 {
71 use core::fmt::{self, Formatter};
72 use core::str::FromStr;
73
74 struct Visitor;
75 impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
76 type Value = $name;
77
78 fn expecting(&self, f: &mut Formatter) -> core::fmt::Result {
79 f.write_str($descr)
80 }
81
82 fn visit_str<E>(self, s: &str) -> core::result::Result<Self::Value, E>
83 where
84 E: $crate::serde::de::Error,
85 {
86 s.parse().map_err(|error| {
87 $crate::serde::IntoDeError::try_into_de_error(error)
88 .unwrap_or_else(|_| E::invalid_value(Unexpected::Str(s), &self))
89 })
90 }
91 }
92
93 deserializer.deserialize_str(Visitor)
94 }
95 }
96
97 #[cfg(feature = "serde")]
98 impl $crate::serde::Serialize for $name {
99 fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
100 where
101 S: $crate::serde::Serializer,
102 {
103 serializer.collect_str(&self)
104 }
105 }
106 }
107}