1
1
use std:: ptr;
2
+
2
3
use thiserror:: Error ;
3
4
4
5
pub mod ffi {
@@ -16,8 +17,8 @@ pub mod ffi {
16
17
pub length : usize ,
17
18
}
18
19
19
- impl AsRef < str > for ada_string {
20
- fn as_ref ( & self ) -> & str {
20
+ impl ada_string {
21
+ pub fn as_str ( self ) -> & ' static str {
21
22
unsafe {
22
23
let slice = std:: slice:: from_raw_parts ( self . data . cast ( ) , self . length ) ;
23
24
std:: str:: from_utf8_unchecked ( slice)
@@ -61,7 +62,7 @@ pub mod ffi {
61
62
pub fn ada_get_url_components ( url : * mut ada_url ) -> ada_url_components ;
62
63
63
64
// Getters
64
- pub fn ada_get_origin ( url : * mut ada_url ) -> ada_owned_string ;
65
+ pub fn ada_get_origin ( url : * mut ada_url ) -> * mut ada_owned_string ;
65
66
pub fn ada_get_href ( url : * mut ada_url ) -> ada_string ;
66
67
pub fn ada_get_username ( url : * mut ada_url ) -> ada_string ;
67
68
pub fn ada_get_password ( url : * mut ada_url ) -> ada_string ;
@@ -112,10 +113,12 @@ pub struct Url {
112
113
113
114
impl Drop for Url {
114
115
fn drop ( & mut self ) {
115
- unsafe {
116
- if let Some ( origin ) = self . origin {
116
+ if let Some ( origin ) = self . origin {
117
+ unsafe {
117
118
ffi:: ada_free_owned_string ( origin) ;
118
119
}
120
+ }
121
+ unsafe {
119
122
ffi:: ada_free ( self . url ) ;
120
123
}
121
124
}
@@ -126,62 +129,63 @@ impl Url {
126
129
unsafe {
127
130
ffi:: ada_can_parse (
128
131
input. as_ptr ( ) . cast ( ) ,
129
- base. unwrap_or_else ( ptr :: null ( ) ) . as_ptr ( ) . cast ( ) ,
132
+ base. map ( |b| b . as_ptr ( ) ) . unwrap_or ( ptr :: null_mut ( ) ) . cast ( ) ,
130
133
)
131
134
}
132
135
}
133
136
134
137
pub fn origin ( & mut self ) -> & str {
135
138
unsafe {
136
- self . origin = ffi:: ada_get_origin ( self . url ) ;
137
- return self . origin . as_ref ( ) ;
139
+ self . origin = Some ( ffi:: ada_get_origin ( self . url ) ) ;
140
+ self . origin . map ( |o| ( * o ) . as_ref ( ) ) . unwrap_or ( "" )
138
141
}
139
142
}
140
143
141
144
pub fn href ( & self ) -> & str {
142
- unsafe { ffi:: ada_get_href ( self . url ) . as_ref ( ) }
145
+ unsafe { ffi:: ada_get_href ( self . url ) } . as_str ( )
143
146
}
144
147
145
148
pub fn username ( & self ) -> & str {
146
- unsafe { ffi:: ada_get_username ( self . url ) . as_ref ( ) }
149
+ unsafe { ffi:: ada_get_username ( self . url ) } . as_str ( )
147
150
}
148
151
149
152
pub fn password ( & self ) -> & str {
150
- unsafe { ffi:: ada_get_password ( self . url ) . as_ref ( ) }
153
+ unsafe { ffi:: ada_get_password ( self . url ) } . as_str ( )
151
154
}
152
155
153
156
pub fn port ( & self ) -> & str {
154
- unsafe { ffi:: ada_get_port ( self . url ) . as_ref ( ) }
157
+ unsafe { ffi:: ada_get_port ( self . url ) } . as_str ( )
155
158
}
156
159
157
160
pub fn hash ( & self ) -> & str {
158
- unsafe { ffi:: ada_get_hash ( self . url ) . as_ref ( ) }
161
+ unsafe { ffi:: ada_get_hash ( self . url ) } . as_str ( )
159
162
}
160
163
161
164
pub fn host ( & self ) -> & str {
162
- unsafe { ffi:: ada_get_host ( self . url ) . as_ref ( ) }
165
+ unsafe { ffi:: ada_get_host ( self . url ) } . as_str ( )
163
166
}
164
167
165
168
pub fn hostname ( & self ) -> & str {
166
- unsafe { ffi:: ada_get_hostname ( self . url ) . as_ref ( ) }
169
+ unsafe { ffi:: ada_get_hostname ( self . url ) } . as_str ( )
167
170
}
168
171
169
172
pub fn pathname ( & self ) -> & str {
170
- unsafe { ffi:: ada_get_pathname ( self . url ) . as_ref ( ) }
173
+ unsafe { ffi:: ada_get_pathname ( self . url ) } . as_str ( )
171
174
}
172
175
173
176
pub fn search ( & self ) -> & str {
174
- unsafe { ffi:: ada_get_search ( self . url ) . as_ref ( ) }
177
+ unsafe { ffi:: ada_get_search ( self . url ) } . as_str ( )
175
178
}
176
179
177
180
pub fn protocol ( & self ) -> & str {
178
- unsafe { ffi:: ada_get_protocol ( self . url ) . as_ref ( ) }
181
+ unsafe { ffi:: ada_get_protocol ( self . url ) } . as_str ( )
179
182
}
180
183
}
181
184
182
185
pub fn parse < U : AsRef < str > > ( url : U ) -> Result < Url , Error > {
186
+ let url_with_0_terminate = std:: ffi:: CString :: new ( url. as_ref ( ) ) . unwrap ( ) ;
183
187
unsafe {
184
- let mut url_aggregator = ffi:: ada_parse ( url . as_ref ( ) . as_ptr ( ) . cast ( ) ) ;
188
+ let url_aggregator = ffi:: ada_parse ( url_with_0_terminate . as_ptr ( ) ) ;
185
189
186
190
if ffi:: ada_is_valid ( url_aggregator) {
187
191
Ok ( Url {
@@ -193,3 +197,13 @@ pub fn parse<U: AsRef<str>>(url: U) -> Result<Url, Error> {
193
197
}
194
198
}
195
199
}
200
+
201
+ #[ cfg( test) ]
202
+ mod test {
203
+ use super :: * ;
204
+
205
+ #[ test]
206
+ fn should_parse_simple_url ( ) {
207
+ assert ! ( parse( "https://google.com" ) . is_ok( ) ) ;
208
+ }
209
+ }
0 commit comments