@@ -67,6 +67,66 @@ impl From<c_uint> for HostType {
67
67
}
68
68
}
69
69
70
+ /// By using 32-bit integers, we implicitly assume that the URL string
71
+ /// cannot exceed 4 GB.
72
+ ///
73
+ /// https://user:[email protected] :1234/foo/bar?baz#quux
74
+ /// | | | | ^^^^| | |
75
+ /// | | | | | | | `----- hash_start
76
+ /// | | | | | | `--------- search_start
77
+ /// | | | | | `----------------- pathname_start
78
+ /// | | | | `--------------------- port
79
+ /// | | | `----------------------- host_end
80
+ /// | | `---------------------------------- host_start
81
+ /// | `--------------------------------------- username_end
82
+ /// `--------------------------------------------- protocol_end
83
+ #[ derive( Debug ) ]
84
+ pub struct UrlComponents {
85
+ pub protocol_end : u32 ,
86
+ pub username_end : u32 ,
87
+ pub host_start : u32 ,
88
+ pub host_end : u32 ,
89
+ pub port : Option < u32 > ,
90
+ pub pathname_start : Option < u32 > ,
91
+ pub search_start : Option < u32 > ,
92
+ pub hash_start : Option < u32 > ,
93
+ }
94
+
95
+ impl From < & ffi:: ada_url_components > for UrlComponents {
96
+ fn from ( value : & ffi:: ada_url_components ) -> Self {
97
+ let port = if value. port == u32:: MAX {
98
+ None
99
+ } else {
100
+ Some ( value. port )
101
+ } ;
102
+ let pathname_start = if value. pathname_start == u32:: MAX {
103
+ None
104
+ } else {
105
+ Some ( value. pathname_start )
106
+ } ;
107
+ let search_start = if value. search_start == u32:: MAX {
108
+ None
109
+ } else {
110
+ Some ( value. search_start )
111
+ } ;
112
+ let hash_start = if value. hash_start == u32:: MAX {
113
+ None
114
+ } else {
115
+ Some ( value. hash_start )
116
+ } ;
117
+ Self {
118
+ protocol_end : value. protocol_end ,
119
+ username_end : value. username_end ,
120
+ host_start : value. host_start ,
121
+ host_end : value. host_end ,
122
+ port,
123
+ pathname_start,
124
+ search_start,
125
+ hash_start,
126
+ }
127
+ }
128
+ }
129
+
70
130
/// A parsed URL struct according to WHATWG URL specification.
71
131
#[ derive( Eq ) ]
72
132
pub struct Url ( * mut ffi:: ada_url ) ;
@@ -87,7 +147,7 @@ impl Drop for Url {
87
147
88
148
impl From < * mut ffi:: ada_url > for Url {
89
149
fn from ( value : * mut ffi:: ada_url ) -> Self {
90
- Self { 0 : value }
150
+ Self ( value)
91
151
}
92
152
}
93
153
@@ -395,12 +455,18 @@ impl Url {
395
455
pub fn has_search ( & self ) -> bool {
396
456
unsafe { ffi:: ada_has_search ( self . 0 ) }
397
457
}
458
+
398
459
/// Returns the parsed version of the URL with all components.
399
460
///
400
461
/// For more information, read [WHATWG URL spec](https://url.spec.whatwg.org/#dom-url-href)
401
462
pub fn as_str ( & self ) -> & str {
402
463
self . href ( )
403
464
}
465
+
466
+ /// Returns the URL components of the instance.
467
+ pub fn components ( & self ) -> UrlComponents {
468
+ unsafe { ffi:: ada_get_components ( self . 0 ) . as_ref ( ) . unwrap ( ) } . into ( )
469
+ }
404
470
}
405
471
406
472
/// Serializes this URL into a `serde` stream.
@@ -508,48 +574,10 @@ impl From<Url> for String {
508
574
509
575
impl fmt:: Debug for Url {
510
576
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
511
- unsafe {
512
- let components = ffi:: ada_get_components ( self . 0 ) . as_ref ( ) . unwrap ( ) ;
513
- let mut debug = f. debug_struct ( "Url" ) ;
514
- debug
515
- . field ( "href" , & self . href ( ) )
516
- . field ( "protocol_end" , & components. protocol_end )
517
- . field ( "host_start" , & components. host_start )
518
- . field ( "host_end" , & components. host_end ) ;
519
- let port = if components. port == u32:: MAX {
520
- None
521
- } else {
522
- Some ( components. port )
523
- } ;
524
- let username_end = if components. username_end == u32:: MAX {
525
- None
526
- } else {
527
- Some ( components. username_end )
528
- } ;
529
- let search_start = if components. search_start == u32:: MAX {
530
- None
531
- } else {
532
- Some ( components. search_start )
533
- } ;
534
- let hash_start = if components. hash_start == u32:: MAX {
535
- None
536
- } else {
537
- Some ( components. hash_start )
538
- } ;
539
- let pathname_start = if components. pathname_start == u32:: MAX {
540
- None
541
- } else {
542
- Some ( components. pathname_start )
543
- } ;
544
-
545
- debug
546
- . field ( "port" , & port)
547
- . field ( "username_end" , & username_end)
548
- . field ( "search_start" , & search_start)
549
- . field ( "hash_start" , & hash_start)
550
- . field ( "pathname_start" , & pathname_start)
551
- . finish ( )
552
- }
577
+ f. debug_struct ( "Url" )
578
+ . field ( "href" , & self . href ( ) )
579
+ . field ( "components" , & self . components ( ) )
580
+ . finish ( )
553
581
}
554
582
}
555
583
0 commit comments