19
19
//! servo url ▏ 664 ns/URL ███████████▎
20
20
//! CURL ▏ 1471 ns/URL █████████████████████████
21
21
//! ```
22
+ //!
23
+ //! # Feature: `serde`
24
+ //!
25
+ //! If you enable the `serde` feature, [`Url`](struct.Url.html) will implement
26
+ //! [`serde::Serialize`](https://docs.rs/serde/1/serde/trait.Serialize.html) and
27
+ //! [`serde::Deserialize`](https://docs.rs/serde/1/serde/trait.Deserialize.html).
28
+ //! See [serde documentation](https://serde.rs) for more information.
29
+ //!
30
+ //! ```toml
31
+ //! ada-url = { version = "1", features = ["serde"] }
32
+ //! ```
22
33
23
34
pub mod ffi;
24
35
mod idna;
@@ -27,21 +38,23 @@ pub use idna::Idna;
27
38
use std:: { borrow, fmt, hash, ops} ;
28
39
use thiserror:: Error ;
29
40
41
+ #[ cfg( feature = "serde" ) ]
42
+ extern crate serde;
43
+
30
44
#[ derive( Error , Debug ) ]
31
45
pub enum Error {
32
46
#[ error( "Invalid url: \" {0}\" " ) ]
33
47
ParseUrl ( String ) ,
34
48
}
35
49
50
+ #[ derive( Eq ) ]
36
51
pub struct Url {
37
52
url : * mut ffi:: ada_url ,
38
53
}
39
54
40
55
impl Drop for Url {
41
56
fn drop ( & mut self ) {
42
- unsafe {
43
- ffi:: ada_free ( self . url ) ;
44
- }
57
+ unsafe { ffi:: ada_free ( self . url ) }
45
58
}
46
59
}
47
60
@@ -354,15 +367,61 @@ impl Url {
354
367
}
355
368
}
356
369
370
+ /// Serializes this URL into a `serde` stream.
371
+ ///
372
+ /// This implementation is only available if the `serde` Cargo feature is enabled.
373
+ #[ cfg( feature = "serde" ) ]
374
+ impl serde:: Serialize for Url {
375
+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
376
+ where
377
+ S : serde:: Serializer ,
378
+ {
379
+ serializer. serialize_str ( self . as_str ( ) )
380
+ }
381
+ }
382
+
383
+ /// Deserializes this URL from a `serde` stream.
384
+ ///
385
+ /// This implementation is only available if the `serde` Cargo feature is enabled.
386
+ #[ cfg( feature = "serde" ) ]
387
+ impl < ' de > serde:: Deserialize < ' de > for Url {
388
+ fn deserialize < D > ( deserializer : D ) -> Result < Url , D :: Error >
389
+ where
390
+ D : serde:: Deserializer < ' de > ,
391
+ {
392
+ use serde:: de:: { Error , Unexpected , Visitor } ;
393
+
394
+ struct UrlVisitor ;
395
+
396
+ impl < ' de > Visitor < ' de > for UrlVisitor {
397
+ type Value = Url ;
398
+
399
+ fn expecting ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
400
+ formatter. write_str ( "a string representing an URL" )
401
+ }
402
+
403
+ fn visit_str < E > ( self , s : & str ) -> Result < Self :: Value , E >
404
+ where
405
+ E : Error ,
406
+ {
407
+ Url :: parse ( s, None ) . map_err ( |err| {
408
+ let err_s = format ! ( "{}" , err) ;
409
+ Error :: invalid_value ( Unexpected :: Str ( s) , & err_s. as_str ( ) )
410
+ } )
411
+ }
412
+ }
413
+
414
+ deserializer. deserialize_str ( UrlVisitor )
415
+ }
416
+ }
417
+
357
418
/// URLs compare like their stringification.
358
419
impl PartialEq for Url {
359
420
fn eq ( & self , other : & Self ) -> bool {
360
421
self . href ( ) == other. href ( )
361
422
}
362
423
}
363
424
364
- impl Eq for Url { }
365
-
366
425
impl PartialOrd for Url {
367
426
fn partial_cmp ( & self , other : & Self ) -> Option < std:: cmp:: Ordering > {
368
427
self . href ( ) . partial_cmp ( other. href ( ) )
@@ -476,6 +535,7 @@ impl ops::Deref for Url {
476
535
self . href ( )
477
536
}
478
537
}
538
+
479
539
impl AsRef < str > for Url {
480
540
fn as_ref ( & self ) -> & str {
481
541
self . href ( )
0 commit comments