• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // This file is part of ICU4X. For terms of use, please see the file
2 // called LICENSE at the top level of the ICU4X source tree
3 // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4 
5 use alloc::borrow::Cow;
6 use serde::de::Deserializer;
7 use serde::Deserialize;
8 
9 #[derive(Deserialize)]
10 #[serde(transparent)]
11 // Cows fail to borrow in some situations (array, option), but structs of Cows don't.
12 #[allow(clippy::exhaustive_structs)] // newtype
13 #[derive(Debug)]
14 pub struct CowWrap<'data>(#[serde(borrow)] pub Cow<'data, str>);
15 
16 #[derive(Deserialize)]
17 #[serde(transparent)]
18 // Cows fail to borrow in some situations (array, option), but structs of Cows don't.
19 #[allow(clippy::exhaustive_structs)] // newtype
20 #[derive(Debug)]
21 pub struct CowBytesWrap<'data>(#[serde(borrow)] pub Cow<'data, [u8]>);
22 
array_of_cow<'de, D, const N: usize>(deserializer: D) -> Result<[Cow<'de, str>; N], D::Error> where D: Deserializer<'de>, [CowWrap<'de>; N]: Deserialize<'de>,23 pub fn array_of_cow<'de, D, const N: usize>(deserializer: D) -> Result<[Cow<'de, str>; N], D::Error>
24 where
25     D: Deserializer<'de>,
26     [CowWrap<'de>; N]: Deserialize<'de>,
27 {
28     <[CowWrap<'de>; N]>::deserialize(deserializer).map(|array| array.map(|wrap| wrap.0))
29 }
30 
option_of_cow<'de, D>(deserializer: D) -> Result<Option<Cow<'de, str>>, D::Error> where D: Deserializer<'de>,31 pub fn option_of_cow<'de, D>(deserializer: D) -> Result<Option<Cow<'de, str>>, D::Error>
32 where
33     D: Deserializer<'de>,
34 {
35     <Option<CowWrap<'de>>>::deserialize(deserializer).map(|opt| opt.map(|wrap| wrap.0))
36 }
37 
tuple_of_cow<'de, D>(deserializer: D) -> Result<(Cow<'de, str>, Cow<'de, str>), D::Error> where D: Deserializer<'de>, (CowWrap<'de>, CowWrap<'de>): Deserialize<'de>,38 pub fn tuple_of_cow<'de, D>(deserializer: D) -> Result<(Cow<'de, str>, Cow<'de, str>), D::Error>
39 where
40     D: Deserializer<'de>,
41     (CowWrap<'de>, CowWrap<'de>): Deserialize<'de>,
42 {
43     <(CowWrap<'de>, CowWrap<'de>)>::deserialize(deserializer).map(|x| (x.0 .0, x.1 .0))
44 }
45 
46 #[test]
test_option()47 fn test_option() {
48     #[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
49     struct Demo<'s>(#[serde(borrow, deserialize_with = "option_of_cow")] Option<Cow<'s, str>>);
50 
51     let data_orig = Demo(Some("Hello world".into()));
52     let json = serde_json::to_string(&data_orig).expect("serialize");
53     let data_new = serde_json::from_str::<Demo>(&json).expect("deserialize");
54     assert_eq!(data_orig, data_new);
55     assert!(matches!(data_new.0, Some(Cow::Borrowed(_))));
56 }
57 
58 #[test]
test_tuple()59 fn test_tuple() {
60     #[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
61     struct Demo<'s>(
62         #[serde(borrow, deserialize_with = "tuple_of_cow")] (Cow<'s, str>, Cow<'s, str>),
63     );
64 
65     let data_orig = Demo(("Hello world".into(), "Hello earth".into()));
66     let json = serde_json::to_string(&data_orig).expect("serialize");
67     let data_new = serde_json::from_str::<Demo>(&json).expect("deserialize");
68     assert_eq!(data_orig, data_new);
69     assert!(matches!(data_new.0, (Cow::Borrowed(_), Cow::Borrowed(_))));
70 }
71 
72 #[test]
test_array()73 fn test_array() {
74     #[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
75     struct Demo<'s>(#[serde(borrow, deserialize_with = "array_of_cow")] [Cow<'s, str>; 1]);
76 
77     let data_orig = Demo(["Hello world".into()]);
78     let json = serde_json::to_string(&data_orig).expect("serialize");
79     let data_new = serde_json::from_str::<Demo>(&json).expect("deserialize");
80     assert_eq!(data_orig, data_new);
81     assert!(matches!(data_new.0, [Cow::Borrowed(_)]));
82 }
83