@@ -1825,6 +1825,87 @@ pub struct PickFirst<T>(PhantomData<T>);
1825
1825
/// ```
1826
1826
pub struct FromInto < T > ( PhantomData < T > ) ;
1827
1827
1828
+ /// Serialize a reference value by converting to/from a proxy type with serde support.
1829
+ ///
1830
+ /// This adapter serializes a type `O` by converting it into a second type `T` and serializing `T`.
1831
+ /// Deserializing works analogue, by deserializing a `T` and then converting into `O`.
1832
+ ///
1833
+ /// ```rust
1834
+ /// # #[cfg(FALSE)] {
1835
+ /// struct S {
1836
+ /// #[serde_as(as = "FromIntoRef<T>")]
1837
+ /// value: O,
1838
+ /// }
1839
+ /// # }
1840
+ /// ```
1841
+ ///
1842
+ /// For serialization `O` needs to be `for<'a> &'a O: Into<T>`.
1843
+ /// For deserialization the opposite `T: Into<O>` is required.
1844
+ ///
1845
+ /// **Note**: [`TryFromIntoRef`] is the more generalized version of this adapter which uses the [`TryInto`](std::convert::TryInto) trait instead.
1846
+ ///
1847
+ /// # Example
1848
+ ///
1849
+ /// ```rust
1850
+ /// # #[cfg(feature = "macros")] {
1851
+ /// # use serde::{Deserialize, Serialize};
1852
+ /// # use serde_json::json;
1853
+ /// # use serde_with::{serde_as, FromIntoRef};
1854
+ /// #
1855
+ /// #[derive(Debug, PartialEq)]
1856
+ /// struct Rgb {
1857
+ /// red: u8,
1858
+ /// green: u8,
1859
+ /// blue: u8,
1860
+ /// }
1861
+ ///
1862
+ /// # /*
1863
+ /// impl From<(u8, u8, u8)> for Rgb { ... }
1864
+ /// impl From<Rgb> for (u8, u8, u8) { ... }
1865
+ /// # */
1866
+ /// #
1867
+ /// # impl From<(u8, u8, u8)> for Rgb {
1868
+ /// # fn from(v: (u8, u8, u8)) -> Self {
1869
+ /// # Rgb {
1870
+ /// # red: v.0,
1871
+ /// # green: v.1,
1872
+ /// # blue: v.2,
1873
+ /// # }
1874
+ /// # }
1875
+ /// # }
1876
+ /// #
1877
+ /// # impl<'a> From<&'a Rgb> for (u8, u8, u8) {
1878
+ /// # fn from(v: &'a Rgb) -> Self {
1879
+ /// # (v.red, v.green, v.blue)
1880
+ /// # }
1881
+ /// # }
1882
+ ///
1883
+ /// #[serde_as]
1884
+ /// # #[derive(Debug, PartialEq)]
1885
+ /// #[derive(Deserialize, Serialize)]
1886
+ /// struct Color {
1887
+ /// #[serde_as(as = "FromIntoRef<(u8, u8, u8)>")]
1888
+ /// rgb: Rgb,
1889
+ /// }
1890
+ /// let color = Color {
1891
+ /// rgb: Rgb {
1892
+ /// red: 128,
1893
+ /// green: 64,
1894
+ /// blue: 32,
1895
+ /// },
1896
+ /// };
1897
+ ///
1898
+ /// // Define our expected JSON form
1899
+ /// let j = json!({
1900
+ /// "rgb": [128, 64, 32],
1901
+ /// });
1902
+ /// // Ensure serialization and deserialization produce the expected results
1903
+ /// assert_eq!(j, serde_json::to_value(&color).unwrap());
1904
+ /// assert_eq!(color, serde_json::from_value(j).unwrap());
1905
+ /// # }
1906
+ /// ```
1907
+ pub struct FromIntoRef < T > ( PhantomData < T > ) ;
1908
+
1828
1909
/// Serialize value by converting to/from a proxy type with serde support.
1829
1910
///
1830
1911
/// This adapter serializes a type `O` by converting it into a second type `T` and serializing `T`.
@@ -1915,6 +1996,95 @@ pub struct FromInto<T>(PhantomData<T>);
1915
1996
/// ```
1916
1997
pub struct TryFromInto < T > ( PhantomData < T > ) ;
1917
1998
1999
+ /// Serialize a reference value by converting to/from a proxy type with serde support.
2000
+ ///
2001
+ /// This adapter serializes a type `O` by converting it into a second type `T` and serializing `T`.
2002
+ /// Deserializing works analogue, by deserializing a `T` and then converting into `O`.
2003
+ ///
2004
+ /// ```rust
2005
+ /// # #[cfg(FALSE)] {
2006
+ /// struct S {
2007
+ /// #[serde_as(as = "TryFromIntoRef<T>")]
2008
+ /// value: O,
2009
+ /// }
2010
+ /// # }
2011
+ /// ```
2012
+ ///
2013
+ /// For serialization `O` needs to be `for<'a> &'a O: TryInto<T>`.
2014
+ /// For deserialization the opposite `T: TryInto<O>` is required.
2015
+ /// In both cases the `TryInto::Error` type must implement [`Display`](std::fmt::Display).
2016
+ ///
2017
+ /// **Note**: [`FromIntoRef`] is the more specialized version of this adapter which uses the infallible [`Into`] trait instead.
2018
+ /// [`TryFromIntoRef`] is strictly more general and can also be used where [`FromIntoRef`] is applicable.
2019
+ /// The example shows a use case, when only the deserialization behavior is fallible, but not serializing.
2020
+ ///
2021
+ /// # Example
2022
+ ///
2023
+ /// ```rust
2024
+ /// # #[cfg(feature = "macros")] {
2025
+ /// # use serde::{Deserialize, Serialize};
2026
+ /// # use serde_json::json;
2027
+ /// # use serde_with::{serde_as, TryFromIntoRef};
2028
+ /// # use std::convert::TryFrom;
2029
+ /// #
2030
+ /// #[derive(Debug, PartialEq)]
2031
+ /// enum Boollike {
2032
+ /// True,
2033
+ /// False,
2034
+ /// }
2035
+ ///
2036
+ /// # /*
2037
+ /// impl From<Boollike> for u8 { ... }
2038
+ /// # */
2039
+ /// #
2040
+ /// impl TryFrom<u8> for Boollike {
2041
+ /// type Error = String;
2042
+ /// fn try_from(v: u8) -> Result<Self, Self::Error> {
2043
+ /// match v {
2044
+ /// 0 => Ok(Boollike::False),
2045
+ /// 1 => Ok(Boollike::True),
2046
+ /// _ => Err(format!("Boolikes can only be constructed from 0 or 1 but found {}", v))
2047
+ /// }
2048
+ /// }
2049
+ /// }
2050
+ /// #
2051
+ /// # impl<'a> From<&'a Boollike> for u8 {
2052
+ /// # fn from(v: &'a Boollike) -> Self {
2053
+ /// # match v {
2054
+ /// # Boollike::True => 1,
2055
+ /// # Boollike::False => 0,
2056
+ /// # }
2057
+ /// # }
2058
+ /// # }
2059
+ ///
2060
+ /// #[serde_as]
2061
+ /// # #[derive(Debug, PartialEq)]
2062
+ /// #[derive(Deserialize, Serialize)]
2063
+ /// struct Data {
2064
+ /// #[serde_as(as = "TryFromIntoRef<u8>")]
2065
+ /// b: Boollike,
2066
+ /// }
2067
+ /// let data = Data {
2068
+ /// b: Boollike::True,
2069
+ /// };
2070
+ ///
2071
+ /// // Define our expected JSON form
2072
+ /// let j = json!({
2073
+ /// "b": 1,
2074
+ /// });
2075
+ /// // Ensure serialization and deserialization produce the expected results
2076
+ /// assert_eq!(j, serde_json::to_value(&data).unwrap());
2077
+ /// assert_eq!(data, serde_json::from_value(j).unwrap());
2078
+ ///
2079
+ /// // Numbers besides 0 or 1 should be an error
2080
+ /// let j = json!({
2081
+ /// "b": 2,
2082
+ /// });
2083
+ /// assert_eq!("Boolikes can only be constructed from 0 or 1 but found 2", serde_json::from_value::<Data>(j).unwrap_err().to_string());
2084
+ /// # }
2085
+ /// ```
2086
+ pub struct TryFromIntoRef < T > ( PhantomData < T > ) ;
2087
+
1918
2088
/// Borrow `Cow` data during deserialization when possible.
1919
2089
///
1920
2090
/// The types `Cow<'a, [u8]>`, `Cow<'a, [u8; N]>`, and `Cow<'a, str>` can borrow from the input data during deserialization.
0 commit comments