rubedo/serde.rs
1//! This module provides conversion utility functions for use with [Serde](https://crates.io/crates/serde).
2//!
3//! This module attempts to consider the common use cases for (de)serialisation,
4//! and provide functions that are semantically appropriate for those use cases.
5//! The functions are intended to be used with the
6//! [`#[serde(serialize_with)]`](https://docs.serde.rs/serde/attr.serialize_with.html)
7//! and [`#[serde(deserialize_with)]`](https://docs.serde.rs/serde/attr.deserialize_with.html)
8//! attributes.
9//!
10//! Of course, as this module is an *extension* of standard Serde functionality,
11//! it does not attempt to reproduce what Serde already does by default. For
12//! instance, if a struct has a field of type [`u32`], then Serde will already
13//! know how to serialise and deserialise that field. Equally, if a struct has a
14//! field that is an enum, then Serde is able to serialise and deserialise that
15//! field according to the available enum variants, and the chosen internal
16//! representation of the enum.
17//!
18//! Where this module provides particular value is when an alternative
19//! serialised representation is required for certain struct members. For
20//! example, it is common to have an enum that naturally serialises to and from
21//! an integer, but also has a string representation. Or equally, it could be
22//! that the required serialised form is not the default. This module allows
23//! easy specification of alternative forms for serialisation and
24//! deserialisation, while working with the existing Serde derive macros.
25//!
26//! As a general statement, the intention of this module is to provide this
27//! functionality for data types such as structs and enums, where the Serde
28//! derive macros would be used, and there is no obvious application for
29//! primitive types such as integers, floats, and booleans, or string types such
30//! as [`String`] and [`str`].
31//!
32//! # Naming conventions
33//!
34//! Generally in Rust, the naming of functions carries semantic meaning:
35//!
36//! - `to_` prefix: This implies a conversion that does not necessarily
37//! consume the original value. It's often seen in methods that return a new
38//! value based on the original, without consuming the original.
39//!
40//! - `into_` prefix: This indicates that the function consumes the original
41//! value and transforms it into another. It's commonly used with Rust's
42//! ownership system, signifying that the original value will no longer be
43//! usable after the conversion.
44//!
45//! - `as_` prefix: This is typically used for cheap reference conversions
46//! that don't involve any data processing. It suggests a view or
47//! representation of the original value, not a conversion or
48//! transformation.
49//!
50//! # `From` and `Into`
51//!
52//! The first case considered is general conversion using [`Into`] and [`From`].
53//! In a situation where a type implements [`Into<T>`](Into) and either
54//! [`From<T>`](From) or [`TryFrom<T>`](TryFrom), then it seems natural and
55//! appropriate to be able to use those implementations for serialisation and
56//! deserialisation. Indeed, Serde does allow this, and it is possible to use
57//! the [`#[serde(into)]`](https://serde.rs/container-attrs.html#into),
58//! and [`#[serde(from)]`](https://serde.rs/container-attrs.html#from), and
59//! and [`#[serde(try_from)]`](https://serde.rs/container-attrs.html#try_from)
60//! attributes to specify the desired primary types. However, these apply at the
61//! container level, and there are no equivalent attributes for specifying the
62//! same behaviour at the field level. Instead, the [`#[serde(with)]`](https://serde.rs/field-attrs.html#with)
63//! attribute can be used, but this requires the implementation of a custom
64//! serialiser and/or deserialiser. That's where this module comes in.
65//!
66//! The [`into()`], [`from()`], and [`try_from()`] functions can be used to
67//! specify the desired behaviour at the field level, matching the behaviour of
68//! the Serde container-level attributes, without the need to implement custom
69//! serialisers and deserialisers. This allows for variations other than the
70//! default to be easily specified. Additionally, ease-of-use functions for
71//! [`String`] conversion are provided in the form of [`into_string()`],
72//! [`from_string()`], and [`try_from_string()`]. Note that these functions
73//! expect to work on a full [`String`], not a [`str`] slice, due to their
74//! context.
75//!
76//! The end result is that it becomes trivial to specify alternate conversions
77//! for any type that implements the common conversion traits.
78//!
79//! # `Display` and `ToString`, and `FromStr`
80//!
81//! Implementing [`Display`] for a type adds a free implementation of
82//! [`ToString`] as well, which provides the [`to_string()`](ToString::to_string())
83//! method. This is intended to be used for human-readable representations of a
84//! type, and provides a [`String`] copy of the converted type. This is not
85//! necessarily the same as the serialised representation, which is intended for
86//! machine-readable uses. However, for cases where the [`Display`]
87//! implementation is the same as the serialised representation, it is possible
88//! to use the [`to_string()`] function to provide the desired behaviour.
89//!
90//! Notably, this is conceptually a subset of the [`Into<String>`](Into) use
91//! case, as [`Into<String>`](Into) is intended to be used for any type that can
92//! be converted to a [`String`], and [`ToString`] does that as well, albeit
93//! with a different semantic purpose, and via copy versus consumption. Although
94//! it is *advised* to use the [`into_string()`] or [`as_str()`] functions
95//! instead (as appropriate), the [`to_string()`] Serde helper function is
96//! provided for completeness and for such cases where a [`Display`]
97//! implementation may exist and is the same as the serialised form, in which
98//! case it would be onerous to also implement another function just for the
99//! sake of it.
100//!
101//! The other side of the [`ToString`] coin is [`FromStr`], which provides the
102//! [`from_str()`](FromStr::from_str()) method. This is intended to be used for
103//! parsing a [`String`] into a type, and is the counterpart to [`to_string()`].
104//! For this purpose, the [`from_str()`] function is provided, which is
105//! basically equivalent to [`from()`], but for [`String`] types. In this way,
106//! it serves the same essential purpose as [`from_string()`], but for types
107//! that implement [`FromStr`] instead of [`TryFrom<String>`](TryFrom). That is
108//! the only difference, and the choice of which to use is entirely down to the
109//! implementation of the type in question.
110//!
111//! # `AsStr`
112//!
113//! The second case considered is representation using [`AsStr`]. The
114//! [`as_str()`] function is intended to be used with any type that implements
115//! the [`AsStr`] trait, which provides an [`as_str()`](AsStr::as_str()) method.
116//! This function is primarily intended to be used with enums, where it is
117//! common to have variants that naturally serialise to and from integers, but
118//! also have a string representation. In such cases, the enums will typically
119//! be created with `static &str` values for such representation, in which case
120//! it is desirable to use and propagate those actual values by reference
121//! instead of making unnecessary copies. This is the purpose of the
122//! [`as_str()`] function.
123//!
124//! In keeping with Rust naming conventions and idioms, the concept of
125//! representation is considered to be distinct from the concept of conversion,
126//! with this function providing an unmodified, uncopied "view" onto a value
127//! provided by the type for this purpose.
128//!
129
130
131
132// Modules
133
134#[cfg(test)]
135#[path = "tests/serde.rs"]
136mod tests;
137
138
139
140// Packages
141
142use crate::std::{AsStr, FromIntWithScale, ToIntWithScale};
143use core::{
144 fmt::Display,
145 str::FromStr,
146};
147use rust_decimal::Decimal;
148use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error as DeError, ser::Error as SerError};
149
150
151
152// Functions
153
154// as_str
155/// Returns a string representation of a type from a string slice.
156///
157/// This can be used with any type that implements [`AsStr`], but it is perhaps
158/// most useful when applied to enums. There is no `AsStr` trait in core Rust at
159/// present, but as the focus of this function is representation as [`str`], it
160/// seems best and most intuitive to name it `as_str()`. It is distinct in
161/// purpose from the [`Display`] trait, which is intended for human-readable
162/// representations, and provides [`ToString`].
163///
164/// It is a fairly common pattern to have an enum that naturally serialises to
165/// and from an integer, but also has a string representation. Or equally, it
166/// could be that the required serialised form is not the default, which would
167/// be to use the variant name. This function allows the correct string
168/// representation to be obtained from the enum value.
169///
170/// It is different from the [`Display`] implementation in that it returns a
171/// serialised representation of the enum (or indeed other type), suitable for
172/// exchanging via serialised data, rather than a human-readable representation.
173///
174/// This function is intended for use by [`serde`] to serialise the enum or
175/// other type of interest, e.g. when using [`#[serde(serialize_with)]`]:
176///
177/// ```ignore
178/// #[serde(serialize_with = "as_str")]
179/// ```
180///
181/// So in summary:
182///
183/// - [`Display`] is for human-readable representations. This also implements
184/// [`ToString`], which provides the [`to_string()`](ToString::to_string())
185/// method. The semantic purpose is *conversion to* a string. This concept
186/// of conversion signifies that the resulting string is not "the thing",
187/// but a description of it, and reversing the process is not necessarily
188/// guaranteed to be possible, and also may not have a 1:1 relationship.
189///
190/// - [`Into<String>`](Into) is for attempting an infallible conversion that
191/// takes, transforms, and consumes the original value. It may be different
192/// in intent and purpose from the [`Display`] implementation, but the
193/// technical difference is simply that `to_` functions convert by cloning,
194/// and `into_` functions convert by consuming. The semantic purpose is
195/// *transformation into* a string. This concept in this current context
196/// signifies that the resulting string is *equivalent to* "the thing", just
197/// in a different form, which can be used to recreate the original and is
198/// for all intents and purposes equivalent to it, but involves a process of
199/// fundamental type conversion rather than a presentation of something
200/// already present.
201///
202/// - [`AsStr`] is different in intent and purpose from both [`Display`] and
203/// [`Into<String>`](Into). It is intended to be used with types that have a
204/// method that returns a [`str`] slice, usually built-in as a static part
205/// of themselves, and therefore providing another "view" of the type. The
206/// semantic purpose is *representation as* a string. This concept signifies
207/// that the resulting string *is* "the thing", just viewed in a different
208/// way, which can be used to recreate the original and did not involve any
209/// conversion in order to provide.
210///
211/// The [`AsStr`] implementation is therefore typically a "lightweight" method
212/// of getting type representation, and the [`Into<String>`](Into)
213/// implementation is a more "heavyweight" approach.
214///
215/// Note that there may be cause to implement both [`Into<String>`](Into) and
216/// `AsStr` for a type, such as an enum, but the latter may well simply call the
217/// former.
218///
219/// # Parameters
220///
221/// * `value` - The value to serialise.
222/// * `serializer` - The serialiser to use.
223///
224/// # Errors
225///
226/// This function will return an error if the value cannot be serialised to a
227/// [`String`]. The error will be a [`Serializer::Error`], which is passed
228/// through from the [`serde`] crate.
229///
230/// Note that the actual provision of `T` as a [`str`] is infallible, but the
231/// serialisation process may experience an error.
232///
233/// # See also
234///
235/// * [`into_string()`]
236/// * [`to_string()`]
237///
238pub fn as_str<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
239where
240 T: AsStr,
241 S: Serializer,
242{
243 serializer.serialize_str(value.as_str())
244}
245
246// to_string
247/// Returns a string copy of a type.
248///
249/// This can be used with any type that implements [`ToString`], which is
250/// usually achieved by implementing [`Display`]. Although this is typically
251/// intended for human-readable representations, using it for serialisation can
252/// be useful in cases where this matches the serialised representation.
253///
254/// This function is intended for use by [`serde`] to serialise the type of
255/// interest, e.g. when using [`#[serde(serialize_with)]`]:
256///
257/// ```ignore
258/// #[serde(serialize_with = "to_string")]
259/// ```
260///
261/// The equivalent opposite of this function is [`from_str()`], which is
262/// intended for use with [`FromStr`].
263///
264/// # Parameters
265///
266/// * `value` - The value to serialise.
267/// * `serializer` - The serialiser to use.
268///
269/// # Errors
270///
271/// This function will return an error if the value cannot be serialised to a
272/// [`String`]. The error will be a [`Serializer::Error`], which is passed
273/// through from the [`serde`] crate.
274///
275/// Note that the actual provision of `T` as a [`str`] is infallible, but the
276/// serialisation process may experience an error.
277///
278/// # See also
279///
280/// * [`as_str()`]
281/// * [`from_str()`]
282/// * [`into_string()`]
283///
284pub fn to_string<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
285where
286 T: ToString,
287 S: Serializer,
288{
289 serializer.serialize_str(&value.to_string())
290}
291
292// from_str
293/// Returns a type from a string slice representation.
294///
295/// This can be used with any type that implements [`FromStr`]. It is basically
296/// the opposite of [`to_string()`], and is intended to be used for parsing a
297/// [`String`] into a type, and is essentially equivalent to [`from_string()`],
298/// but for types that implement [`FromStr`] instead of [`TryFrom<String>`](TryFrom).
299///
300/// This function is intended for use by [`serde`] to deserialise the type of
301/// interest, e.g. when using [`#[serde(deserialize_with)]`]:
302///
303/// ```ignore
304/// #[serde(deserialize_with = "from_str")]
305/// ```
306///
307/// The equivalent opposite of this function is [`to_string()`], which is
308/// intended for use with [`ToString`].
309///
310/// # Parameters
311///
312/// * `deserializer` - The deserialiser to use.
313///
314/// # Errors
315///
316/// This function will return an error if the deserialised value cannot be
317/// converted to the required type. The error will be a [`DeError`], which is
318/// passed through from the [`serde`] crate.
319///
320/// Note that the actual conversion of the [`String`] to `T` is infallible, but
321/// the deserialisation process may experience an error.
322///
323/// # See also
324///
325/// * [`try_from()`]
326/// * [`from_str()`]
327/// * [`into_string()`]
328/// * [`try_from_string()`]
329///
330pub fn from_str<'de, T, D>(deserializer: D) -> Result<T, D::Error>
331where
332 T: FromStr,
333 T::Err: Display,
334 D: Deserializer<'de>,
335{
336 T::from_str(&String::deserialize(deserializer)?).map_err(DeError::custom)
337}
338
339// into
340/// Returns a serialised representation of a type.
341///
342/// This can be used with any type that implements [`Into<T>`](Into), which
343/// comes for free when implementing [`From<T>`](From), but it is perhaps most
344/// useful when applied to enums. Note that **both** `Into<U> for T` **AND**
345/// `Into<U> for &T` need to be implemented (usually via `From<T> for U` and
346/// `From<&T> for U`), due to the way Serde handles generic cases like this.
347///
348/// It is a fairly common pattern to have an enum that naturally serialises to
349/// and from an integer, but also has a string representation. Or equally, it
350/// could be that the required serialised form is not the default, which would
351/// be to use the variant name. This function allows the correct string
352/// representation to be obtained from the enum value. However, because it
353/// relies upon [`Into`], it can be used with any type that implements that
354/// trait and has a serialised representation.
355///
356/// It is different from the [`Display`] implementation in that it returns a
357/// serialised representation of the enum (or indeed other type), suitable for
358/// exchanging via serialised data, rather than a human-readable representation.
359///
360/// This function is intended for use by [`serde`] to serialise the enum or
361/// other type of interest, e.g. when using [`#[serde(serialize_with)]`]:
362///
363/// ```ignore
364/// #[serde(serialize_with = "into::<Foo, String, __S>")]
365/// ```
366///
367/// Note that the example above will specify [`String`] as the concrete type
368/// that the serialiser will attempt to serialise into. Any type that [`serde`]
369/// supports can be used here, but it must be specified explicitly. Because
370/// converting to a [`String`] is such a common use case, there is a convenience
371/// function, [`into_string()`], that can be used instead. This achieves the
372/// same result as the example above, but is more concise:
373///
374/// ```ignore
375/// #[serde(serialize_with = "into_string")]
376/// ```
377///
378/// In the [`into()`] example, `Foo` is the type that is being serialised, which
379/// will result in a conversion to [`String`]. It needs to be specified because
380/// the output type requires an annotation, as it cannot be inferred, and there
381/// is no way to specify the output type without also specifying the input type.
382/// This is another reason why [`into_string()`] is more concise, as it does not
383/// require the input type to be specified.
384///
385/// So in summary:
386///
387/// - [`Display`] is for human-readable representations. This also implements
388/// [`ToString`], which provides the [`to_string()`](ToString::to_string())
389/// method. The semantic purpose is *conversion to* a string. This concept
390/// of conversion signifies that the resulting string is not "the thing",
391/// but a description of it, and reversing the process is not necessarily
392/// guaranteed to be possible, and also may not have a 1:1 relationship.
393///
394/// - [`Into<String>`](Into) is for attempting an infallible conversion that
395/// takes, transforms, and consumes the original value. It may be different
396/// in intent and purpose from the [`Display`] implementation, but the
397/// technical difference is simply that `to_` functions convert by cloning,
398/// and `into_` functions convert by consuming. The semantic purpose is
399/// *transformation into* a string. This concept in this current context
400/// signifies that the resulting string is *equivalent to* "the thing", just
401/// in a different form, which can be used to recreate the original and is
402/// for all intents and purposes equivalent to it, but involves a process of
403/// fundamental type conversion rather than a presentation of something
404/// already present.
405///
406/// Conversion to a [`String`] has a number of semantic possibilities. However,
407/// there is a general premise that there is generally only one correct
408/// serialised string representation of a given value, and that other string
409/// representations are not representative of the serialised form. This is not
410/// the case for general conversion to a [`String`], where there is no such
411/// assumption. For example, the [`Display`] implementation for an enum may
412/// return a string representation that is not the same as the serialised form,
413/// as it is intended for a different purpose. However, the function written to
414/// implement [`Into`] should output the string representation that is
415/// considered to be authoritative.
416///
417/// Note that, unlike with deserialisation using [`try_from()`], there is only
418/// one serialised type possibility supported by this function, which is `U`. If
419/// there is a need to serialise to other types, then the [`Serialize`] trait
420/// should be implemented directly.
421///
422/// # Parameters
423///
424/// * `value` - The value to serialise.
425/// * `serializer` - The serialiser to use.
426///
427/// # Errors
428///
429/// This function will return an error if the value cannot be serialised to a
430/// [`String`]. The error will be a [`Serializer::Error`], which is passed
431/// through from the [`serde`] crate.
432///
433/// Note that the actual conversion of `T` to `U` is infallible, but the
434/// serialisation process may experience an error.
435///
436/// # See also
437///
438/// * [`from()`]
439/// * [`into_string()`]
440/// * [`try_from()`]
441///
442pub fn into<T, U, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
443where
444 T: Into<U>,
445 U: Serialize + for<'a > From<&'a T>,
446 S: Serializer,
447{
448 let converted: U = value.into();
449 converted.serialize(serializer)
450}
451
452// into_string
453/// Returns string representation of a type.
454///
455/// This is a convenience function that can be used instead of [`into()`] when
456/// when the output type is [`String`]:
457///
458/// ```ignore
459/// #[serde(serialize_with = "into_string")]
460/// ```
461///
462/// It is equivalent to the following:
463///
464/// ```ignore
465/// #[serde(serialize_with = "into::<T, String, __S>")]
466/// ```
467///
468/// It can be used with any type that implements [`Into<String>`](Into), which
469/// comes for free when implementing [`From<T>`](From) for [`String`], but it is
470/// perhaps most useful when applied to enums. Note that, unlike with the
471/// generic [`into()`] function, only `Into<String> for &T` needs to be
472/// implemented (usually via `From<&T> for String`), and not `Into<String> for
473/// T` as well.
474///
475/// Note also that, unlike with deserialisation using [`try_from_string()`],
476/// there is only one serialised type supported by this function, which is
477/// [`String`]. If there is a need to serialise to other types, then the
478/// [`Serialize`] trait should be implemented directly.
479///
480/// For more information, see the documentation for [`into()`].
481///
482/// For a lightweight alternative to provide representation rather than
483/// conversion, see [`as_str()`].
484///
485/// # Parameters
486///
487/// * `value` - The value to serialise.
488/// * `serializer` - The serialiser to use.
489///
490/// # Errors
491///
492/// This function will return an error if the value cannot be serialised to a
493/// [`String`]. The error will be a [`Serializer::Error`], which is passed
494/// through from the [`serde`] crate.
495///
496/// Note that the actual conversion of `T` to a [`String`] is infallible, but
497/// the serialisation process may experience an error.
498///
499/// # See also
500///
501/// * [`as_str()`]
502/// * [`from()`]
503/// * [`into()`]
504/// * [`to_string()`]
505/// * [`try_from_string()`]
506///
507pub fn into_string<T, S>(value: T, serializer: S) -> Result<S::Ok, S::Error>
508where
509 T: Into<String>,
510 S: Serializer,
511{
512 serializer.serialize_str(&value.into())
513}
514
515// from
516/// Returns a type from a string or other serialised representation.
517///
518/// This can be used with any type that implements [`From<String>`](From), but
519/// it is perhaps most useful when applied to enums.
520///
521/// It is a fairly common pattern to have an enum that naturally serialises to
522/// and from an integer, but also has a string representation. Or equally, it
523/// could be that the required serialised form is not the default, which would
524/// be to use the variant name. This function allows the correct string
525/// representation to be used to obtain the appropriate enum value. However,
526/// because it relies upon [`From`], it can be used with any type that
527/// implements that trait and has a serialised representation.
528///
529/// This function is intended for use by [`serde`] to deserialise the enum or
530/// other type of interest, e.g. when using [`#[serde(deserialize_with)]`]:
531///
532/// ```ignore
533/// #[serde(deserialize_with = "from::<Foo, String, __D>")]
534/// ```
535///
536/// Note that the example above will specify [`String`] as the concrete type
537/// that the deserialiser will attempt to deserialise from. Any type that
538/// [`serde`] supports can be used here, but it must be specified explicitly.
539/// Because converting from a [`String`] is such a common use case, there is a
540/// convenience function, [`from_string()`], that can be used instead. This
541/// achieves the same result as the example above, but is more concise:
542///
543/// ```ignore
544/// #[serde(deserialize_with = "from_string")]
545/// ```
546///
547/// In the [`from()`] example, `Foo` is the type that is being deserialised,
548/// which will be the result of the conversion. It needs to be specified because
549/// the input type requires an annotation, as it cannot be inferred, and there
550/// is no way to specify the input type without also specifying the output type.
551/// This is another reason why [`from_string()`] is more concise, as it does not
552/// require the output type to be specified.
553///
554/// Conversion from a [`String`] does not share the same number of semantic
555/// possibilities as conversion to a [`String`]. There is a general premise that
556/// there is generally only one correct serialised string representation of a
557/// given value, and that other string representations are not representative of
558/// the serialised form. This is not the case for conversion to a [`String`],
559/// where there is no such assumption. For example, the [`Display`]
560/// implementation for an enum may return a string representation that is not
561/// the same as the serialised form, as it is intended for a different purpose.
562/// However, the function written to implement [`From`] can of course do
563/// whatever it likes, and can support any number of string representations.
564///
565/// # Parameters
566///
567/// * `deserializer` - The deserialiser to use.
568///
569/// # Errors
570///
571/// This function will return an error if the deserialised value cannot be
572/// converted to the required type. The error will be a [`DeError`], which is
573/// passed through from the [`serde`] crate.
574///
575/// Note that the actual conversion of `U` to `T` is infallible, but the
576/// deserialisation process may experience an error.
577///
578/// # See also
579///
580/// * [`into()`]
581/// * [`from_str()`]
582/// * [`from_string()`]
583/// * [`try_from()`]
584///
585pub fn from<'de, T, U, D>(deserializer: D) -> Result<T, D::Error>
586where
587 T: From<U>,
588 U: Deserialize<'de>,
589 D: Deserializer<'de>,
590{
591 U::deserialize(deserializer).map(T::from)
592}
593
594// from_string
595/// Returns a type from a string representation.
596///
597/// This is a convenience function that can be used instead of [`from()`] when
598/// the input type is [`String`]:
599///
600/// ```ignore
601/// #[serde(deserialize_with = "from_string")]
602/// ```
603///
604/// It is equivalent to the following:
605///
606/// ```ignore
607/// #[serde(deserialize_with = "from::<T, String, __D>")]
608/// ```
609///
610/// For more information, see the documentation for [`from()`].
611///
612/// # Parameters
613///
614/// * `deserializer` - The deserialiser to use.
615///
616/// # Errors
617///
618/// This function will return an error if the deserialised value cannot be
619/// converted to the required type. The error will be a [`DeError`], which is
620/// passed through from the [`serde`] crate.
621///
622/// Note that the actual conversion of the [`String`] to `T` is infallible, but
623/// the deserialisation process may experience an error.
624///
625/// # See also
626///
627/// * [`from()`]
628/// * [`from_str()`]
629/// * [`into_string()`]
630/// * [`try_from_string()`]
631///
632pub fn from_string<'de, T, D>(deserializer: D) -> Result<T, D::Error>
633where
634 T: From<String>,
635 D: Deserializer<'de>,
636{
637 String::deserialize(deserializer).map(T::from)
638}
639
640// try_from
641/// Returns a type from a string or other serialised representation.
642///
643/// This can be used with any type that implements [`TryFrom<String>`](TryFrom),
644/// but it is perhaps most useful when applied to enums.
645///
646/// It is a fairly common pattern to have an enum that naturally serialises to
647/// and from an integer, but also has a string representation. Or equally, it
648/// could be that the required serialised form is not the default, which would
649/// be to use the variant name. This function allows the correct string
650/// representation to be used to obtain the appropriate enum value. However,
651/// because it relies upon [`TryFrom`], it can be used with any type that
652/// implements that trait and has a serialised representation.
653///
654/// This function is intended for use by [`serde`] to deserialise the enum or
655/// other type of interest, e.g. when using [`#[serde(deserialize_with)]`]:
656///
657/// ```ignore
658/// #[serde(deserialize_with = "try_from::<Foo, String, __D>")]
659/// ```
660///
661/// Note that the example above will specify [`String`] as the concrete type
662/// that the deserialiser will attempt to deserialise from. Any type that
663/// [`serde`] supports can be used here, but it must be specified explicitly.
664/// Because converting from a [`String`] is such a common use case, there is a
665/// convenience function, [`try_from_string()`], that can be used instead. This
666/// achieves the same result as the example above, but is more concise:
667///
668/// ```ignore
669/// #[serde(deserialize_with = "try_from_string")]
670/// ```
671///
672/// In the [`try_from()`] example, `Foo` is the type that is being deserialised,
673/// which will be the result of the conversion. It needs to be specified because
674/// the input type requires an annotation, as it cannot be inferred, and there
675/// is no way to specify the input type without also specifying the output type.
676/// This is another reason why [`try_from_string()`] is more concise, as it does
677/// not require the output type to be specified.
678///
679/// Conversion from a [`String`] does not share the same number of semantic
680/// possibilities as conversion to a [`String`]. There is a general premise that
681/// there is generally only one correct serialised string representation of a
682/// given value, and that other string representations are not representative of
683/// the serialised form. This is not the case for conversion to a [`String`],
684/// where there is no such assumption. For example, the [`Display`]
685/// implementation for an enum may return a string representation that is not
686/// the same as the serialised form, as it is intended for a different purpose.
687/// However, the function written to implement [`TryFrom`] can of course do
688/// whatever it likes, and can support any number of string representations.
689///
690/// # Parameters
691///
692/// * `deserializer` - The deserialiser to use.
693///
694/// # Errors
695///
696/// This function will return an error if the deserialised value cannot be
697/// converted to the required type. The error will be a [`DeError`], which is
698/// passed through from the [`serde`] crate.
699///
700/// It will also return an error if the conversion from `U` to `T` fails. The
701/// nature of this error will be specific to the type being converted to.
702///
703/// # See also
704///
705/// * [`from()`]
706/// * [`from_str()`]
707/// * [`into()`]
708/// * [`try_from_string()`]
709///
710pub fn try_from<'de, T, U, D>(deserializer: D) -> Result<T, D::Error>
711where
712 T: TryFrom<U>,
713 U: Deserialize<'de>,
714 T::Error: Display,
715 D: Deserializer<'de>,
716{
717 T::try_from(U::deserialize(deserializer)?).map_err(DeError::custom)
718}
719
720// try_from_string
721/// Returns a type from a string representation.
722///
723/// This is a convenience function that can be used instead of [`try_from()`]
724/// when the input type is [`String`]:
725///
726/// ```ignore
727/// #[serde(deserialize_with = "try_from_string")]
728/// ```
729///
730/// It is equivalent to the following:
731///
732/// ```ignore
733/// #[serde(deserialize_with = "try_from::<T, String, __D>")]
734/// ```
735///
736/// For more information, see the documentation for [`try_from()`].
737///
738/// # Parameters
739///
740/// * `deserializer` - The deserialiser to use.
741///
742/// # Errors
743///
744/// This function will return an error if the deserialised value cannot be
745/// converted to the required type. The error will be a [`DeError`], which is
746/// passed through from the [`serde`] crate.
747///
748/// It will also return an error if the conversion from the [`String`] to `T`
749/// fails. The nature of this error will be specific to the type being converted
750/// to.
751///
752/// # See also
753///
754/// * [`from_str()`]
755/// * [`from_string()`]
756/// * [`into_string()`]
757/// * [`try_from()`]
758///
759pub fn try_from_string<'de, T, D>(deserializer: D) -> Result<T, D::Error>
760where
761 T: TryFrom<String>,
762 T::Error: Display,
763 D: Deserializer<'de>,
764{
765 T::try_from(String::deserialize(deserializer)?).map_err(DeError::custom)
766}
767
768// try_from_int_with_scale
769/// Converts an integer to a floating-point number with scale.
770///
771/// This function takes an integer which represents a decimal value to a
772/// specified number of decimal places, and converts it to a floating-point
773/// number. So for instance, the integer `12345` could be converted to the
774/// floating-point number `123.45` if the scale is 2.
775///
776/// It is intended for use by [`serde`], indirectly when using the following
777/// convenience functions with [`#[serde(deserialize_with)]`]:
778///
779/// ```ignore
780/// #[serde(deserialize_with = "try_from_int_1dp::<T, i64, __D>")]
781/// #[serde(deserialize_with = "try_from_int_2dp::<T, i64, __D>")]
782/// #[serde(deserialize_with = "try_from_int_3dp::<T, i64, __D>")]
783/// #[serde(deserialize_with = "try_from_int_4dp::<T, i64, __D>")]
784/// ```
785///
786/// Note that the examples above will specify [`i64`] as the concrete type that
787/// the deserialiser will attempt to deserialise from. Any integer type can be
788/// used here, or indeed any type recognised by an implementation of
789/// [`FromIntWithScale`], but it must be specified explicitly.
790///
791/// # Parameters
792///
793/// * `deserializer` - The deserialiser to use.
794/// * `scale` - The scale factor, i.e. the number of decimal places. Note
795/// that this is essentially limited to a maximum of 19 DP of
796/// movement for an [`f32`] or [`f64`] without overflowing,
797/// and 28 DP for a [`Decimal`].
798///
799/// # Errors
800///
801/// This function will return an error if the deserialised value cannot be
802/// converted to the required type. The error will be a [`DeError`], which is
803/// passed through from the [`serde`] crate.
804///
805/// It will also return an error if the conversion from the integer to `T`
806/// fails. The nature of this error will be specific to the type being converted
807/// to.
808///
809/// # See also
810///
811/// * [`from_cents()`]
812/// * [`from_pence()`]
813/// * [`try_from_int_1dp()`]
814/// * [`try_from_int_2dp()`]
815/// * [`try_from_int_3dp()`]
816/// * [`try_from_int_4dp()`]
817/// * [`try_to_int_with_scale()`]
818///
819pub fn try_from_int_with_scale<'de, T, U, D>(deserializer: D, scale: u8) -> Result<T, D::Error>
820where
821 T: FromIntWithScale<U>,
822 U: Deserialize<'de>,
823 D: Deserializer<'de>,
824{
825 T::from_int_with_scale(U::deserialize(deserializer)?, scale)
826 .ok_or_else(|| DeError::custom("Failed to convert from integer with scale"))
827}
828
829// try_from_int_1dp
830/// Converts an integer to a floating-point number to 1 decimal place.
831///
832/// This is a convenience function — see [`try_from_int_with_scale()`].
833///
834/// # Parameters
835///
836/// * `deserializer` - The deserialiser to use.
837///
838/// # Errors
839///
840/// See [`try_from_int_with_scale()`].
841///
842/// # See also
843///
844/// * [`try_from_int_2dp()`]
845/// * [`try_from_int_3dp()`]
846/// * [`try_from_int_4dp()`]
847/// * [`try_to_int_1dp()`]
848///
849pub fn try_from_int_1dp<'de, T, U, D>(deserializer: D) -> Result<T, D::Error>
850where
851 T: FromIntWithScale<U>,
852 U: Deserialize<'de>,
853 D: Deserializer<'de>,
854{
855 try_from_int_with_scale(deserializer, 1)
856}
857
858// try_from_int_2dp
859/// Converts an integer to a floating-point number to 2 decimal places.
860///
861/// This is a convenience function — see [`try_from_int_with_scale()`].
862///
863/// # Parameters
864///
865/// * `deserializer` - The deserialiser to use.
866///
867/// # Errors
868///
869/// See [`try_from_int_with_scale()`].
870///
871/// # See also
872///
873/// * [`from_cents()`]
874/// * [`from_pence()`]
875/// * [`try_from_int_1dp()`]
876/// * [`try_from_int_3dp()`]
877/// * [`try_from_int_4dp()`]
878/// * [`try_to_int_2dp()`]
879///
880pub fn try_from_int_2dp<'de, T, U, D>(deserializer: D) -> Result<T, D::Error>
881where
882 T: FromIntWithScale<U>,
883 U: Deserialize<'de>,
884 D: Deserializer<'de>,
885{
886 try_from_int_with_scale(deserializer, 2)
887}
888
889// try_from_int_3dp
890/// Converts an integer to a floating-point number to 3 decimal places.
891///
892/// This is a convenience function — see [`try_from_int_with_scale()`].
893///
894/// # Parameters
895///
896/// * `deserializer` - The deserialiser to use.
897///
898/// # Errors
899///
900/// See [`try_from_int_with_scale()`].
901///
902/// # See also
903///
904/// * [`try_from_int_1dp()`]
905/// * [`try_from_int_2dp()`]
906/// * [`try_from_int_4dp()`]
907/// * [`try_to_int_3dp()`]
908///
909pub fn try_from_int_3dp<'de, T, U, D>(deserializer: D) -> Result<T, D::Error>
910where
911 T: FromIntWithScale<U>,
912 U: Deserialize<'de>,
913 D: Deserializer<'de>,
914{
915 try_from_int_with_scale(deserializer, 3)
916}
917
918// try_from_int_4dp
919/// Converts an integer to a floating-point number to 4 decimal places.
920///
921/// This is a convenience function — see [`try_from_int_with_scale()`].
922///
923/// # Parameters
924///
925/// * `deserializer` - The deserialiser to use.
926///
927/// # Errors
928///
929/// See [`try_from_int_with_scale()`].
930///
931/// # See also
932///
933/// * [`try_from_int_1dp()`]
934/// * [`try_from_int_2dp()`]
935/// * [`try_from_int_3dp()`]
936/// * [`try_to_int_4dp()`]
937///
938pub fn try_from_int_4dp<'de, T, U, D>(deserializer: D) -> Result<T, D::Error>
939where
940 T: FromIntWithScale<U>,
941 U: Deserialize<'de>,
942 D: Deserializer<'de>,
943{
944 try_from_int_with_scale(deserializer, 4)
945}
946
947// try_to_int_with_scale
948/// Converts a floating-point number to an integer with scale.
949///
950/// This function takes a floating-point number and converts it to an integer
951/// which represents a decimal value to a specified number of decimal places. So
952/// for instance, the floating-point number `123.45` could be converted to the
953/// integer `12345` if the scale is 2.
954///
955/// It is intended for use by [`serde`], indirectly when using the following
956/// convenience functions with [`#[serde(serialize_with)]`]:
957///
958/// ```ignore
959/// #[serde(serialize_with = "try_to_int_1dp::<T, i64, __S>")]
960/// #[serde(serialize_with = "try_to_int_2dp::<T, i64, __S>")]
961/// #[serde(serialize_with = "try_to_int_3dp::<T, i64, __S>")]
962/// #[serde(serialize_with = "try_to_int_4dp::<T, i64, __S>")]
963/// ```
964///
965/// Note that the examples above will specify [`i64`] as the concrete type that
966/// the serialiser will attempt to serialise to. Any integer type can be used
967/// here, or indeed any type recognised by an implementation of
968/// [`ToIntWithScale`], but it must be specified explicitly.
969///
970/// # Parameters
971///
972/// * `serializer` - The serialiser to use.
973/// * `scale` - The scale factor, i.e. the number of decimal places. Note
974/// that this is essentially limited to a maximum of 19 DP of
975/// movement without overflowing.
976///
977/// # Errors
978///
979/// This function will return an error if the value cannot be serialised to the
980/// the required type. The error will be a [`DeError`], which is passed through
981/// from the [`serde`] crate.
982///
983/// It will also return an error if the conversion from `T` to the integer type
984/// fails. The nature of this error will be specific to the type being converted
985/// from.
986///
987/// # See also
988///
989/// * [`to_cents()`]
990/// * [`to_pence()`]
991/// * [`try_from_int_with_scale()`]
992/// * [`try_to_int_1dp()`]
993/// * [`try_to_int_2dp()`]
994/// * [`try_to_int_3dp()`]
995/// * [`try_to_int_4dp()`]
996///
997pub fn try_to_int_with_scale<T, U, S>(value: &T, serializer: S, scale: u8) -> Result<S::Ok, S::Error>
998where
999 T: ToIntWithScale<U>,
1000 U: Serialize,
1001 S: Serializer,
1002{
1003 T::to_int_with_scale(value, scale)
1004 .ok_or_else(|| SerError::custom("Failed to convert to integer with scale"))?
1005 .serialize(serializer)
1006}
1007
1008// try_to_int_1dp
1009/// Converts a floating-point number to an integer to 1 decimal place.
1010///
1011/// This is a convenience function — see [`try_to_int_with_scale()`].
1012///
1013/// # Parameters
1014///
1015/// * `serializer` - The serialiser to use.
1016///
1017/// # Errors
1018///
1019/// See [`try_to_int_with_scale()`].
1020///
1021/// # See also
1022///
1023/// * [`try_from_int_1dp()`]
1024/// * [`try_to_int_2dp()`]
1025/// * [`try_to_int_3dp()`]
1026/// * [`try_to_int_4dp()`]
1027///
1028pub fn try_to_int_1dp<T, U, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
1029where
1030 T: ToIntWithScale<U>,
1031 U: Serialize,
1032 S: Serializer,
1033{
1034 try_to_int_with_scale(value, serializer, 1)
1035}
1036
1037// try_to_int_2dp
1038/// Converts a floating-point number to an integer to 2 decimal places.
1039///
1040/// This is a convenience function — see [`try_to_int_with_scale()`].
1041///
1042/// # Parameters
1043///
1044/// * `serializer` - The serialiser to use.
1045///
1046/// # Errors
1047///
1048/// See [`try_to_int_with_scale()`].
1049///
1050/// # See also
1051///
1052/// * [`to_cents()`]
1053/// * [`to_pence()`]
1054/// * [`try_from_int_2dp()`]
1055/// * [`try_to_int_1dp()`]
1056/// * [`try_to_int_3dp()`]
1057/// * [`try_to_int_4dp()`]
1058///
1059pub fn try_to_int_2dp<T, U, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
1060where
1061 T: ToIntWithScale<U>,
1062 U: Serialize,
1063 S: Serializer,
1064{
1065 try_to_int_with_scale(value, serializer, 2)
1066}
1067
1068// try_to_int_3dp
1069/// Converts a floating-point number to an integer to 3 decimal places.
1070///
1071/// This is a convenience function — see [`try_to_int_with_scale()`].
1072///
1073/// # Parameters
1074///
1075/// * `serializer` - The serialiser to use.
1076///
1077/// # Errors
1078///
1079/// See [`try_to_int_with_scale()`].
1080///
1081/// # See also
1082///
1083/// * [`try_from_int_3dp()`]
1084/// * [`try_to_int_1dp()`]
1085/// * [`try_to_int_2dp()`]
1086/// * [`try_to_int_4dp()`]
1087///
1088pub fn try_to_int_3dp<T, U, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
1089where
1090 T: ToIntWithScale<U>,
1091 U: Serialize,
1092 S: Serializer,
1093{
1094 try_to_int_with_scale(value, serializer, 3)
1095}
1096
1097// try_to_int_4dp
1098/// Converts a floating-point number to an integer to 4 decimal places.
1099///
1100/// This is a convenience function — see [`try_to_int_with_scale()`].
1101///
1102/// # Parameters
1103///
1104/// * `serializer` - The serialiser to use.
1105///
1106/// # Errors
1107///
1108/// See [`try_to_int_with_scale()`].
1109///
1110/// # See also
1111///
1112/// * [`try_from_int_4dp()`]
1113/// * [`try_to_int_1dp()`]
1114/// * [`try_to_int_2dp()`]
1115/// * [`try_to_int_3dp()`]
1116///
1117pub fn try_to_int_4dp<T, U, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
1118where
1119 T: ToIntWithScale<U>,
1120 U: Serialize,
1121 S: Serializer,
1122{
1123 try_to_int_with_scale(value, serializer, 4)
1124}
1125
1126// from_cents
1127/// Converts an integer to a [`Decimal`] to 2 decimal places.
1128///
1129/// This is a convenience function that can be used instead of
1130/// [`try_from_int_2dp()`] when the input type is [`i64`] and the output type
1131/// is [`Decimal`]:
1132///
1133/// ```ignore
1134/// #[serde(deserialize_with = "from_cents")]
1135/// ```
1136///
1137/// It is equivalent to the following:
1138///
1139/// ```ignore
1140/// #[serde(deserialize_with = "try_from_int_2dp::<Decimal, i64, __D>")]
1141/// ```
1142///
1143/// This function takes an [`i64`] integer which represents a decimal value to 2
1144/// DP, and converts it to a [`Decimal`]. So for instance, the integer `12345`
1145/// would be converted to the decimal number `123.45`. The types were chosen
1146/// because [`Decimal`] is the safest to use for currency values (floats should
1147/// never be used as they are not safe), and [`i64`] is the most common integer
1148/// type in this context.
1149///
1150/// For more information, see the documentation for
1151/// [`try_from_int_with_scale()`].
1152///
1153/// # Parameters
1154///
1155/// * `deserializer` - The deserialiser to use.
1156///
1157/// # Errors
1158///
1159/// This function will return an error if the deserialised value cannot be
1160/// converted to the required type. The error will be a [`DeError`], which is
1161/// passed through from the [`serde`] crate.
1162///
1163/// It will also return an error if the conversion from the [`i64`] to
1164/// [`Decimal`] fails (which should never happen). The nature of this error will
1165/// be specific to the type being converted to.
1166///
1167/// # See also
1168///
1169/// * [`from_pence()`]
1170/// * [`to_cents()`]
1171/// * [`try_from_int_2dp()`]
1172///
1173pub fn from_cents<'de, D>(deserializer: D) -> Result<Decimal, D::Error>
1174where
1175 D: Deserializer<'de>,
1176{
1177 try_from_int_2dp::<Decimal, i64, D>(deserializer)
1178}
1179
1180// to_cents
1181/// Converts a [`Decimal`] to an integer to 2 decimal places.
1182///
1183/// This is a convenience function that can be used instead of
1184/// [`try_to_int_2dp()`] when the input type is [`Decimal`] and the output type
1185/// is [`i64`]:
1186///
1187/// ```ignore
1188/// #[serde(serialize_with = "to_cents")]
1189/// ```
1190///
1191/// It is equivalent to the following:
1192///
1193/// ```ignore
1194/// #[serde(serialize_with = "try_to_int_2dp::<Decimal, i64, __S>")]
1195/// ```
1196///
1197/// This function takes a [`Decimal`], and converts it to an integer which
1198/// represents a decimal value to 2 DP. So for instance, the decimal `123.45`
1199/// would be converted to the integer `12345`. The types were chosen because
1200/// [`Decimal`] is the safest to use for currency values (floats should never be
1201/// used as they are not safe), and [`i64`] is the most common integer type in
1202/// this context.
1203///
1204/// For more information, see the documentation for
1205/// [`try_to_int_with_scale()`].
1206///
1207/// # Parameters
1208///
1209/// * `serializer` - The serialiser to use.
1210///
1211/// # Errors
1212///
1213/// This function will return an error if the value cannot be serialised to the
1214/// the required type. The error will be a [`DeError`], which is passed through
1215/// from the [`serde`] crate.
1216///
1217/// It will also return an error if the conversion from [`Decimal`] to [`i64`]
1218/// fails (for instance if the decimal is larger than can fit into the integer's
1219/// range). The nature of this error will be specific to the type being
1220/// converted from.
1221///
1222/// # See also
1223///
1224/// * [`from_cents()`]
1225/// * [`to_pence()`]
1226/// * [`try_to_int_2dp()`]
1227///
1228pub fn to_cents<S>(value: &Decimal, serializer: S) -> Result<S::Ok, S::Error>
1229where
1230 S: Serializer,
1231{
1232 try_to_int_2dp::<Decimal, i64, S>(value, serializer)
1233}
1234
1235// from_pence
1236/// Converts an integer to a [`Decimal`] to 2 decimal places.
1237///
1238/// This is an alias of [`from_cents()`] for convenience.
1239///
1240/// # Parameters
1241///
1242/// * `deserializer` - The deserialiser to use.
1243///
1244/// # Errors
1245///
1246/// See [`from_cents()`].
1247///
1248/// # See also
1249///
1250/// * [`from_cents()`]
1251/// * [`to_pence()`]
1252/// * [`try_from_int_2dp()`]
1253///
1254pub fn from_pence<'de, D>(deserializer: D) -> Result<Decimal, D::Error>
1255where
1256 D: Deserializer<'de>,
1257{
1258 from_cents(deserializer)
1259}
1260
1261// to_pence
1262/// Converts a [`Decimal`] to an integer to 2 decimal places.
1263///
1264/// This is an alias of [`to_cents()`] for convenience.
1265///
1266/// # Parameters
1267///
1268/// * `serializer` - The serialiser to use.
1269///
1270/// # Errors
1271///
1272/// See [`to_cents()`].
1273///
1274/// # See also
1275///
1276/// * [`from_pence()`]
1277/// * [`to_cents()`]
1278/// * [`try_to_int_2dp()`]
1279///
1280pub fn to_pence<S>(value: &Decimal, serializer: S) -> Result<S::Ok, S::Error>
1281where
1282 S: Serializer,
1283{
1284 to_cents(value, serializer)
1285}
1286
1287