@@ -51,9 +51,12 @@ ipc::channel::<Serde<Url>>()
51
51
extern crate serde;
52
52
extern crate url;
53
53
54
+ #[ cfg( test) ]
55
+ #[ macro_use]
56
+ extern crate serde_derive;
57
+
54
58
use std:: cmp:: PartialEq ;
55
59
use std:: fmt;
56
- use std:: hash:: { Hash , Hasher } ;
57
60
use std:: ops:: { Deref , DerefMut } ;
58
61
use std:: error:: Error ;
59
62
use serde:: { Deserialize , Serialize , Serializer , Deserializer } ;
@@ -95,6 +98,18 @@ impl<'a> Serialize for Ser<'a, Url> {
95
98
}
96
99
97
100
101
+ /// Serializes this Option<URL> into a `serde` stream.
102
+ impl < ' a > Serialize for Ser < ' a , Option < Url > > {
103
+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error > where S : Serializer {
104
+ if let Some ( url) = self . 0 . as_ref ( ) {
105
+ serializer. serialize_some ( url. as_str ( ) )
106
+ } else {
107
+ serializer. serialize_none ( )
108
+ }
109
+ }
110
+ }
111
+
112
+
98
113
/// Deserialises a `T` value with a given deserializer.
99
114
///
100
115
/// This is useful to deserialize Url types used in structure fields or
@@ -135,6 +150,21 @@ impl Deserialize for De<Url> {
135
150
}
136
151
137
152
153
+ /// Deserializes this Option<URL> from a `serde` stream.
154
+ impl Deserialize for De < Option < Url > > {
155
+ fn deserialize < D > ( deserializer : D ) -> Result < De < Option < Url > > , D :: Error > where D : Deserializer {
156
+ let option_representation: Option < String > = Deserialize :: deserialize ( deserializer) ?;
157
+ if let Some ( s) = option_representation {
158
+ return Url :: parse ( & s)
159
+ . map ( Some )
160
+ . map ( De )
161
+ . map_err ( |err| { serde:: de:: Error :: custom ( err. description ( ) ) } ) ;
162
+ }
163
+ Ok ( De ( None ) )
164
+
165
+ }
166
+ }
167
+
138
168
/// A convenience wrapper to be used as a type parameter, for example when
139
169
/// a `Vec<T>` or an `HashMap<K, V>` need to be passed to serde.
140
170
#[ derive( Clone , Eq , Hash , PartialEq ) ]
@@ -217,3 +247,95 @@ fn test_ser_de_url() {
217
247
let new_url: Url = serde_json:: from_str ( & s) . map ( De :: into_inner) . unwrap ( ) ;
218
248
assert_eq ! ( url, new_url) ;
219
249
}
250
+
251
+
252
+ #[ test]
253
+ fn test_derive_deserialize_with_for_url ( ) {
254
+ extern crate serde_json;
255
+
256
+ #[ derive( Deserialize , Debug , Eq , PartialEq ) ]
257
+ struct Test {
258
+ #[ serde( deserialize_with = "deserialize" , rename = "_url_" ) ]
259
+ url : Url
260
+ }
261
+
262
+ let url_str = "http://www.test.com/foo/bar?$param=bazz" ;
263
+
264
+ let expected = Test {
265
+ url : Url :: parse ( url_str) . unwrap ( )
266
+ } ;
267
+ let json_string = format ! ( r#"{{"_url_": "{}"}}"# , url_str) ;
268
+ let got: Test = serde_json:: from_str ( & json_string) . unwrap ( ) ;
269
+ assert_eq ! ( expected, got) ;
270
+
271
+ }
272
+
273
+ #[ test]
274
+ fn test_derive_deserialize_with_for_option_url ( ) {
275
+ extern crate serde_json;
276
+
277
+ #[ derive( Deserialize , Debug , Eq , PartialEq ) ]
278
+ struct Test {
279
+ #[ serde( deserialize_with = "deserialize" , rename = "_url_" ) ]
280
+ url : Option < Url >
281
+ }
282
+
283
+ let url_str = "http://www.test.com/foo/bar?$param=bazz" ;
284
+
285
+ let expected = Test {
286
+ url : Some ( Url :: parse ( url_str) . unwrap ( ) )
287
+ } ;
288
+ let json_string = format ! ( r#"{{"_url_": "{}"}}"# , url_str) ;
289
+ let got: Test = serde_json:: from_str ( & json_string) . unwrap ( ) ;
290
+ assert_eq ! ( expected, got) ;
291
+
292
+ let expected = Test {
293
+ url : None
294
+ } ;
295
+ let json_string = r#"{"_url_": null}"# ;
296
+ let got: Test = serde_json:: from_str ( & json_string) . unwrap ( ) ;
297
+ assert_eq ! ( expected, got) ;
298
+ }
299
+
300
+
301
+ #[ test]
302
+ fn test_derive_serialize_with_for_url ( ) {
303
+ extern crate serde_json;
304
+
305
+ #[ derive( Serialize , Debug , Eq , PartialEq ) ]
306
+ struct Test {
307
+ #[ serde( serialize_with = "serialize" , rename = "_url_" ) ]
308
+ url : Url
309
+ }
310
+
311
+ let url_str = "http://www.test.com/foo/bar?$param=bazz" ;
312
+
313
+ let expected = format ! ( r#"{{"_url_":"{}"}}"# , url_str) ;
314
+ let input = Test { url : Url :: parse ( url_str) . unwrap ( ) } ;
315
+ let got = serde_json:: to_string ( & input) . unwrap ( ) ;
316
+ assert_eq ! ( expected, got) ;
317
+ }
318
+
319
+
320
+ #[ test]
321
+ fn test_derive_serialize_with_for_option_url ( ) {
322
+ extern crate serde_json;
323
+
324
+ #[ derive( Serialize , Debug , Eq , PartialEq ) ]
325
+ struct Test {
326
+ #[ serde( serialize_with = "serialize" , rename = "_url_" ) ]
327
+ url : Option < Url >
328
+ }
329
+
330
+ let url_str = "http://www.test.com/foo/bar?$param=bazz" ;
331
+
332
+ let expected = format ! ( r#"{{"_url_":"{}"}}"# , url_str) ;
333
+ let input = Test { url : Some ( Url :: parse ( url_str) . unwrap ( ) ) } ;
334
+ let got = serde_json:: to_string ( & input) . unwrap ( ) ;
335
+ assert_eq ! ( expected, got) ;
336
+
337
+ let expected = format ! ( r#"{{"_url_":null}}"# ) ;
338
+ let input = Test { url : None } ;
339
+ let got = serde_json:: to_string ( & input) . unwrap ( ) ;
340
+ assert_eq ! ( expected, got) ;
341
+ }
0 commit comments