serde_plain/macros.rs
1#[macro_export]
2/// Implements [`FromStr`](std::str::FromStr) for a type that forwards to [`Deserialize`](serde::Deserialize).
3///
4/// ```rust
5/// # #[macro_use] extern crate serde_derive;
6/// use serde::Deserialize;
7/// use serde_plain::derive_fromstr_from_deserialize;
8/// # fn main() {
9///
10/// #[derive(Deserialize, Debug)]
11/// pub enum MyEnum {
12/// VariantA,
13/// VariantB,
14/// }
15///
16/// derive_fromstr_from_deserialize!(MyEnum);
17/// # }
18/// ```
19///
20/// This automatically implements [`FromStr`](std::str::FromStr) which will
21/// invoke the [`from_str`](crate::from_str) method from this crate.
22///
23/// Additionally this macro supports a second argument which can be the
24/// error type to use. In that case `From<serde_plain::Error>` needs
25/// to be implemented for that error.
26///
27/// A third form with a conversion function as second argument is supported.
28/// The closure needs to be in the form `|err| -> ErrType { ... }`:
29///
30/// ```rust
31/// # #[macro_use] extern crate serde_derive;
32/// use serde::Deserialize;
33/// use serde_plain::derive_fromstr_from_deserialize;
34/// # fn main() {
35///
36/// #[derive(Deserialize, Debug)]
37/// pub enum MyEnum {
38/// VariantA,
39/// VariantB,
40/// }
41///
42/// #[derive(Debug)]
43/// pub struct MyError(String);
44///
45/// derive_fromstr_from_deserialize!(MyEnum, |err| -> MyError { MyError(err.to_string()) });
46/// # }
47/// ```
48macro_rules! derive_fromstr_from_deserialize {
49 ($type:ty) => {
50 impl ::std::str::FromStr for $type {
51 type Err = $crate::Error;
52 fn from_str(s: &str) -> ::std::result::Result<$type, Self::Err> {
53 $crate::from_str(s)
54 }
55 }
56 };
57 ($type:ty, |$var:ident| -> $err_type:ty { $err_conv:expr }) => {
58 impl ::std::str::FromStr for $type {
59 type Err = $err_type;
60 fn from_str(s: &str) -> ::std::result::Result<$type, Self::Err> {
61 $crate::from_str(s).map_err(|$var| ($err_conv))
62 }
63 }
64 };
65 ($type:ty, $err_type:ty) => {
66 impl ::std::str::FromStr for $type {
67 type Err = $err_type;
68 fn from_str(s: &str) -> ::std::result::Result<$type, Self::Err> {
69 $crate::from_str(s).map_err(|e| e.into())
70 }
71 }
72 };
73}
74
75/// Legacy alias for [`derive_fromstr_from_deserialize`].
76#[deprecated(note = "legacy alias for derive_fromstr_from_deserialize")]
77#[doc(hidden)]
78#[macro_export]
79macro_rules! forward_from_str_to_serde {
80 ($($tt:tt)*) => { $crate::derive_fromstr_from_deserialize!($($tt)*); }
81}
82
83#[macro_export]
84/// Implements [`Display`](std::fmt::Display) for a type that forwards to [`Serialize`](serde::Serialize).
85///
86/// ```rust
87/// # #[macro_use] extern crate serde_derive;
88/// use serde::Deserialize;
89/// use serde_plain::derive_display_from_serialize;
90/// # fn main() {
91///
92/// #[derive(Serialize, Debug)]
93/// pub enum MyEnum {
94/// VariantA,
95/// VariantB,
96/// }
97///
98/// derive_display_from_serialize!(MyEnum);
99/// # }
100/// ```
101///
102/// This automatically implements [`Display`](std::fmt::Display) which will
103/// invoke the [`to_string`](crate::to_string) method from this crate. In case
104/// that fails the method will panic.
105macro_rules! derive_display_from_serialize {
106 ($type:ident $(:: $type_extra:ident)* < $($lt:lifetime),+ >) => {
107 impl<$($lt,)*> ::std::fmt::Display for $type$(:: $type_extra)*<$($lt,)*> {
108 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
109 write!(f, "{}", $crate::to_string(self).unwrap())
110 }
111 }
112 };
113 ($type:ty) => {
114 impl ::std::fmt::Display for $type {
115 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
116 write!(f, "{}", $crate::to_string(self).unwrap())
117 }
118 }
119 };
120}
121
122/// Legacy alias for [`derive_fromstr_from_serialize`].
123#[deprecated(note = "legacy alias for derive_display_from_serialize")]
124#[doc(hidden)]
125#[macro_export]
126macro_rules! forward_display_to_serde {
127 ($($tt:tt)*) => { $crate::derive_display_from_serialize!($($tt)*); }
128}
129
130/// Derives [`Deserialize`](serde::Serialize) for a type that implements [`FromStr`](std::str::FromStr).
131///
132/// ```rust
133/// use std::str::FromStr;
134/// use std::num::ParseIntError;
135/// use serde_plain::derive_deserialize_from_fromstr;
136/// # fn main() {
137///
138/// pub struct MyStruct(u32);
139///
140/// impl FromStr for MyStruct {
141/// type Err = ParseIntError;
142/// fn from_str(value: &str) -> Result<MyStruct, Self::Err> {
143/// Ok(MyStruct(value.parse()?))
144/// }
145/// }
146///
147/// derive_deserialize_from_fromstr!(MyStruct, "valid positive number");
148/// # }
149/// ```
150///
151/// This automatically implements [`Serialize`](serde::Serialize) which will
152/// invoke the [`from_str`](crate::from_str) function on the target type
153/// internally. First argument is the name of the type, the second is a message
154/// for the expectation error (human readable type effectively).
155#[macro_export]
156macro_rules! derive_deserialize_from_fromstr {
157 ($type:ty, $expectation:expr) => {
158 impl<'de> ::serde::de::Deserialize<'de> for $type {
159 fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
160 where
161 D: ::serde::de::Deserializer<'de>,
162 {
163 struct V;
164
165 impl<'de> ::serde::de::Visitor<'de> for V {
166 type Value = $type;
167
168 fn expecting(
169 &self,
170 formatter: &mut ::std::fmt::Formatter,
171 ) -> ::std::fmt::Result {
172 formatter.write_str($expectation)
173 }
174
175 fn visit_str<E>(self, value: &str) -> ::std::result::Result<$type, E>
176 where
177 E: ::serde::de::Error,
178 {
179 value.parse().map_err(|_| {
180 ::serde::de::Error::invalid_value(
181 ::serde::de::Unexpected::Str(value),
182 &self,
183 )
184 })
185 }
186 }
187
188 deserializer.deserialize_str(V)
189 }
190 }
191 };
192}
193
194/// Legacy alias for [`derive_fromstr_from_deserialize`].
195#[deprecated(note = "legacy alias for derive_deserialize_from_fromstr")]
196#[doc(hidden)]
197#[macro_export]
198macro_rules! derive_deserialize_from_str {
199 ($($tt:tt)*) => { $crate::derive_deserialize_from_fromstr!($($tt)*); }
200}
201
202/// Derives [`Serialize`](serde::Serialize) a type that implements [`Display`](std::fmt::Display).
203///
204/// ```rust
205/// use std::fmt;
206/// use serde_plain::derive_serialize_from_display;
207/// # fn main() {
208///
209/// pub struct MyStruct(u32);
210///
211/// impl fmt::Display for MyStruct {
212/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
213/// write!(f, "{}", self.0)
214/// }
215/// }
216///
217/// derive_serialize_from_display!(MyStruct);
218/// # }
219/// ```
220///
221/// This automatically implements [`Serialize`](serde::Serialize) which will
222/// invoke the [`to_string`](crate::to_string) method on the target.
223#[macro_export]
224macro_rules! derive_serialize_from_display {
225 ($type:ident $(:: $type_extra:ident)* < $($lt:lifetime),+ >) => {
226 impl<$($lt,)*> ::serde::ser::Serialize for $type$(:: $type_extra)*<$($lt,)*> {
227 fn serialize<S>(&self, serializer: S) -> ::std::result::Result<S::Ok, S::Error>
228 where
229 S: ::serde::ser::Serializer,
230 {
231 serializer.serialize_str(&self.to_string())
232 }
233 }
234 };
235 ($type:ty) => {
236 impl ::serde::ser::Serialize for $type {
237 fn serialize<S>(&self, serializer: S) -> ::std::result::Result<S::Ok, S::Error>
238 where
239 S: ::serde::ser::Serializer,
240 {
241 serializer.serialize_str(&self.to_string())
242 }
243 }
244 };
245}
246
247#[test]
248fn test_derive_display_from_serialize_lifetimes() {
249 use serde_derive::Serialize;
250
251 #[derive(Serialize)]
252 struct MyType<'a>(&'a str);
253
254 mod inner {
255 use serde_derive::Serialize;
256
257 #[derive(Serialize)]
258 pub struct MyType<'a>(pub &'a str);
259 }
260
261 derive_display_from_serialize!(MyType<'a>);
262 derive_display_from_serialize!(inner::MyType<'a>);
263
264 assert_eq!(MyType("x").to_string(), "x");
265 assert_eq!(inner::MyType("x").to_string(), "x");
266}
267
268#[test]
269fn test_derive_serialize_from_display_lifetimes() {
270 use serde_derive::Deserialize;
271
272 #[derive(Deserialize)]
273 struct MyType<'a>(&'a str);
274
275 impl<'a> std::fmt::Display for MyType<'a> {
276 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
277 write!(f, "{}", self.0)
278 }
279 }
280
281 mod inner {
282 use serde_derive::Deserialize;
283
284 #[derive(Deserialize)]
285 pub struct MyType<'a>(pub &'a str);
286
287 impl<'a> std::fmt::Display for MyType<'a> {
288 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
289 write!(f, "{}", self.0)
290 }
291 }
292 }
293
294 derive_serialize_from_display!(MyType<'a>);
295 derive_serialize_from_display!(inner::MyType<'a>);
296
297 assert_eq!(crate::to_string(&MyType("x")).unwrap(), "x");
298 assert_eq!(crate::to_string(&inner::MyType("x")).unwrap(), "x");
299}