• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![allow(
2     clippy::derive_partial_eq_without_eq,
3     clippy::items_after_statements,
4     clippy::used_underscore_binding
5 )]
6 
7 use serde::de::value::{BorrowedStrDeserializer, MapDeserializer};
8 use serde::de::{Deserialize, Deserializer, IntoDeserializer};
9 use serde_derive::Deserialize;
10 use serde_test::{assert_de_tokens, assert_de_tokens_error, Token};
11 use std::borrow::Cow;
12 
13 #[test]
test_borrowed_str()14 fn test_borrowed_str() {
15     assert_de_tokens(&"borrowed", &[Token::BorrowedStr("borrowed")]);
16 }
17 
18 #[test]
test_borrowed_str_from_string()19 fn test_borrowed_str_from_string() {
20     assert_de_tokens_error::<&str>(
21         &[Token::String("borrowed")],
22         "invalid type: string \"borrowed\", expected a borrowed string",
23     );
24 }
25 
26 #[test]
test_borrowed_str_from_str()27 fn test_borrowed_str_from_str() {
28     assert_de_tokens_error::<&str>(
29         &[Token::Str("borrowed")],
30         "invalid type: string \"borrowed\", expected a borrowed string",
31     );
32 }
33 
34 #[test]
test_string_from_borrowed_str()35 fn test_string_from_borrowed_str() {
36     assert_de_tokens(&"owned".to_owned(), &[Token::BorrowedStr("owned")]);
37 }
38 
39 #[test]
test_borrowed_bytes()40 fn test_borrowed_bytes() {
41     assert_de_tokens(&&b"borrowed"[..], &[Token::BorrowedBytes(b"borrowed")]);
42 }
43 
44 #[test]
test_borrowed_bytes_from_bytebuf()45 fn test_borrowed_bytes_from_bytebuf() {
46     assert_de_tokens_error::<&[u8]>(
47         &[Token::ByteBuf(b"borrowed")],
48         "invalid type: byte array, expected a borrowed byte array",
49     );
50 }
51 
52 #[test]
test_borrowed_bytes_from_bytes()53 fn test_borrowed_bytes_from_bytes() {
54     assert_de_tokens_error::<&[u8]>(
55         &[Token::Bytes(b"borrowed")],
56         "invalid type: byte array, expected a borrowed byte array",
57     );
58 }
59 
60 #[test]
test_tuple()61 fn test_tuple() {
62     assert_de_tokens(
63         &("str", &b"bytes"[..]),
64         &[
65             Token::Tuple { len: 2 },
66             Token::BorrowedStr("str"),
67             Token::BorrowedBytes(b"bytes"),
68             Token::TupleEnd,
69         ],
70     );
71 }
72 
73 #[test]
test_struct()74 fn test_struct() {
75     #[derive(Deserialize, Debug, PartialEq)]
76     struct Borrowing<'a, 'b> {
77         bs: &'a str,
78         bb: &'b [u8],
79     }
80 
81     assert_de_tokens(
82         &Borrowing {
83             bs: "str",
84             bb: b"bytes",
85         },
86         &[
87             Token::Struct {
88                 name: "Borrowing",
89                 len: 2,
90             },
91             Token::BorrowedStr("bs"),
92             Token::BorrowedStr("str"),
93             Token::BorrowedStr("bb"),
94             Token::BorrowedBytes(b"bytes"),
95             Token::StructEnd,
96         ],
97     );
98 }
99 
100 #[test]
test_field_identifier()101 fn test_field_identifier() {
102     #[derive(Deserialize, Debug, PartialEq)]
103     #[serde(field_identifier)]
104     enum FieldStr<'a> {
105         #[serde(borrow)]
106         Str(&'a str),
107     }
108 
109     assert_de_tokens(&FieldStr::Str("value"), &[Token::BorrowedStr("value")]);
110 
111     #[derive(Deserialize, Debug, PartialEq)]
112     #[serde(field_identifier)]
113     enum FieldBytes<'a> {
114         #[serde(borrow)]
115         Bytes(&'a [u8]),
116     }
117 
118     assert_de_tokens(
119         &FieldBytes::Bytes(b"value"),
120         &[Token::BorrowedBytes(b"value")],
121     );
122 }
123 
124 #[test]
test_cow()125 fn test_cow() {
126     #[derive(Deserialize)]
127     struct Cows<'a, 'b> {
128         copied: Cow<'a, str>,
129 
130         #[serde(borrow)]
131         borrowed: Cow<'b, str>,
132     }
133 
134     struct BorrowedStr(&'static str);
135 
136     impl<'de> IntoDeserializer<'de> for BorrowedStr {
137         type Deserializer = BorrowedStrDeserializer<'de, serde::de::value::Error>;
138 
139         fn into_deserializer(self) -> Self::Deserializer {
140             BorrowedStrDeserializer::new(self.0)
141         }
142     }
143 
144     let de = MapDeserializer::new(IntoIterator::into_iter([
145         ("copied", BorrowedStr("copied")),
146         ("borrowed", BorrowedStr("borrowed")),
147     ]));
148 
149     let cows = Cows::deserialize(de).unwrap();
150 
151     match cows.copied {
152         Cow::Owned(ref s) if s == "copied" => {}
153         _ => panic!("expected a copied string"),
154     }
155 
156     match cows.borrowed {
157         Cow::Borrowed("borrowed") => {}
158         _ => panic!("expected a borrowed string"),
159     }
160 }
161 
162 #[test]
test_lifetimes()163 fn test_lifetimes() {
164     #[derive(Deserialize)]
165     struct Cows<'a, 'b> {
166         _copied: Cow<'a, str>,
167 
168         #[serde(borrow)]
169         _borrowed: Cow<'b, str>,
170     }
171 
172     // Tests that `'de: 'a` is not required by the Deserialize impl.
173     fn _cows_lifetimes<'de: 'b, 'a, 'b, D>(deserializer: D) -> Cows<'a, 'b>
174     where
175         D: Deserializer<'de>,
176     {
177         Deserialize::deserialize(deserializer).unwrap()
178     }
179 
180     #[derive(Deserialize)]
181     struct Wrap<'a, 'b> {
182         #[serde(borrow = "'b")]
183         _cows: Cows<'a, 'b>,
184     }
185 
186     // Tests that `'de: 'a` is not required by the Deserialize impl.
187     fn _wrap_lifetimes<'de: 'b, 'a, 'b, D>(deserializer: D) -> Wrap<'a, 'b>
188     where
189         D: Deserializer<'de>,
190     {
191         Deserialize::deserialize(deserializer).unwrap()
192     }
193 }
194