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