@@ -147,38 +147,210 @@ impl URLSearchParams {
147
147
/// let params = URLSearchParams::parse("a=1&b=2");
148
148
/// assert_eq!(params.to_string(), "a=1&b=2");
149
149
/// ```
150
- pub fn to_string ( & self ) -> & str {
151
- unsafe {
152
- let out = ffi:: ada_search_params_to_string ( self . 0 ) ;
153
- let slice = core:: slice:: from_raw_parts ( out. data . cast ( ) , out. length ) ;
154
- core:: str:: from_utf8_unchecked ( slice)
155
- }
150
+ #[ cfg( feature = "std" ) ]
151
+ #[ allow( clippy:: inherent_to_string) ]
152
+ pub fn to_string ( & self ) -> String {
153
+ unsafe { ffi:: ada_search_params_to_string ( self . 0 ) . to_string ( ) }
156
154
}
157
155
158
156
/// Returns all values of the key.
159
157
///
160
158
/// ```
161
159
/// use ada_url::URLSearchParams;
162
160
/// let params = URLSearchParams::parse("a=1&a=2");
163
- /// assert_eq!(params.get_all("a"), vec!["1", "2"]);
161
+ /// let pairs = params.get_all("a");
162
+ /// assert_eq!(pairs.get_size(), 2);
164
163
/// ```
165
- pub fn get_all ( & self , key : & str ) -> Vec < & str > {
164
+ pub fn get_all ( & self , key : & str ) -> URLSearchParamsEntry {
166
165
unsafe {
167
166
let strings = ffi:: ada_search_params_get_all ( self . 0 , key. as_ptr ( ) . cast ( ) , key. len ( ) ) ;
168
167
let size = ffi:: ada_strings_size ( strings) ;
169
- let mut out = Vec :: with_capacity ( size) ;
170
168
171
- if size == 0 {
172
- return out;
173
- }
169
+ URLSearchParamsEntry :: new ( strings, size)
170
+ }
171
+ }
172
+
173
+ /// Returns all keys as an iterator
174
+ ///
175
+ /// ```
176
+ /// use ada_url::URLSearchParams;
177
+ /// let params = URLSearchParams::parse("a=1");
178
+ /// let mut keys = params.get_keys();
179
+ /// assert!(keys.has_next());
180
+ pub fn get_keys ( & self ) -> URLSearchParamsKeysIterator {
181
+ let iterator = unsafe { ffi:: ada_search_params_get_keys ( self . 0 ) } ;
182
+ URLSearchParamsKeysIterator :: new ( iterator)
183
+ }
184
+
185
+ /// Returns all keys as an iterator
186
+ ///
187
+ /// ```
188
+ /// use ada_url::URLSearchParams;
189
+ /// let params = URLSearchParams::parse("a=1");
190
+ /// let mut values = params.get_values();
191
+ /// assert!(values.has_next());
192
+ pub fn get_values ( & self ) -> URLSearchParamsValuesIterator {
193
+ let iterator = unsafe { ffi:: ada_search_params_get_values ( self . 0 ) } ;
194
+ URLSearchParamsValuesIterator :: new ( iterator)
195
+ }
196
+ }
197
+
198
+ pub struct URLSearchParamsKeysIterator < ' a > {
199
+ iterator : * mut ffi:: ada_url_search_params_keys_iter ,
200
+ _phantom : core:: marker:: PhantomData < & ' a str > ,
201
+ }
202
+
203
+ impl < ' a > Drop for URLSearchParamsKeysIterator < ' a > {
204
+ fn drop ( & mut self ) {
205
+ unsafe { ffi:: ada_free_search_params_keys_iter ( self . iterator ) }
206
+ }
207
+ }
208
+
209
+ impl < ' a > URLSearchParamsKeysIterator < ' a > {
210
+ /// Returns true if iterator has a next value.
211
+ pub fn has_next ( & self ) -> bool {
212
+ unsafe { ffi:: ada_search_params_keys_iter_has_next ( self . iterator ) }
213
+ }
214
+
215
+ /// Returns a new value if it's available
216
+ pub fn get_next ( & self ) -> Option < & str > {
217
+ if self . has_next ( ) {
218
+ return None ;
219
+ }
220
+ let string = unsafe { ffi:: ada_search_params_keys_iter_next ( self . iterator ) } ;
221
+ Some ( string. as_str ( ) )
222
+ }
223
+ }
224
+
225
+ pub struct URLSearchParamsValuesIterator < ' a > {
226
+ iterator : * mut ffi:: ada_url_search_params_values_iter ,
227
+ _phantom : core:: marker:: PhantomData < & ' a str > ,
228
+ }
229
+
230
+ impl < ' a > URLSearchParamsKeysIterator < ' a > {
231
+ fn new ( iterator : * mut ffi:: ada_url_search_params_keys_iter ) -> URLSearchParamsKeysIterator < ' a > {
232
+ URLSearchParamsKeysIterator {
233
+ iterator,
234
+ _phantom : core:: marker:: PhantomData ,
235
+ }
236
+ }
237
+ }
238
+
239
+ impl < ' a > Drop for URLSearchParamsValuesIterator < ' a > {
240
+ fn drop ( & mut self ) {
241
+ unsafe { ffi:: ada_free_search_params_values_iter ( self . iterator ) }
242
+ }
243
+ }
174
244
175
- for index in 0 ..size {
176
- let string = ffi:: ada_strings_get ( strings, index) ;
245
+ impl < ' a > URLSearchParamsValuesIterator < ' a > {
246
+ fn new (
247
+ iterator : * mut ffi:: ada_url_search_params_values_iter ,
248
+ ) -> URLSearchParamsValuesIterator < ' a > {
249
+ URLSearchParamsValuesIterator {
250
+ iterator,
251
+ _phantom : core:: marker:: PhantomData ,
252
+ }
253
+ }
254
+ }
255
+
256
+ impl < ' a > URLSearchParamsValuesIterator < ' a > {
257
+ /// Returns true if iterator has a next value.
258
+ pub fn has_next ( & self ) -> bool {
259
+ unsafe { ffi:: ada_search_params_values_iter_has_next ( self . iterator ) }
260
+ }
261
+
262
+ /// Returns a new value if it's available
263
+ pub fn get_next ( & self ) -> Option < & str > {
264
+ if self . has_next ( ) {
265
+ return None ;
266
+ }
267
+ let string = unsafe { ffi:: ada_search_params_values_iter_next ( self . iterator ) } ;
268
+ Some ( string. as_str ( ) )
269
+ }
270
+ }
271
+
272
+ pub struct URLSearchParamsEntry < ' a > {
273
+ strings : * mut ffi:: ada_strings ,
274
+ size : usize ,
275
+ _phantom : core:: marker:: PhantomData < & ' a str > ,
276
+ }
277
+
278
+ impl < ' a > URLSearchParamsEntry < ' a > {
279
+ fn new ( strings : * mut ffi:: ada_strings , size : usize ) -> URLSearchParamsEntry < ' a > {
280
+ URLSearchParamsEntry {
281
+ strings,
282
+ size,
283
+ _phantom : core:: marker:: PhantomData ,
284
+ }
285
+ }
286
+
287
+ /// Returns whether the key value pair is empty or not
288
+ ///
289
+ /// ```
290
+ /// use ada_url::URLSearchParams;
291
+ /// let params = URLSearchParams::parse("a=1&b=2");
292
+ /// let pairs = params.get_all("a");
293
+ /// assert_eq!(pairs.is_empty(), false);
294
+ /// ```
295
+ pub fn is_empty ( & self ) -> bool {
296
+ self . size == 0
297
+ }
298
+
299
+ /// Returns the size of the key value pairs
300
+ ///
301
+ /// ```
302
+ /// use ada_url::URLSearchParams;
303
+ /// let params = URLSearchParams::parse("a=1&b=2");
304
+ /// let pairs = params.get_all("a");
305
+ /// assert_eq!(pairs.get_size(), 1);
306
+ /// ```
307
+ pub fn get_size ( & self ) -> usize {
308
+ self . size
309
+ }
310
+
311
+ /// Get an entry by index
312
+ ///
313
+ /// ```
314
+ /// use ada_url::URLSearchParams;
315
+ /// let params = URLSearchParams::parse("a=1&a=2");
316
+ /// let pairs = params.get_all("a");
317
+ /// assert_eq!(pairs.get_size(), 2);
318
+ /// assert_eq!(pairs.get(0), Some("1"));
319
+ /// assert_eq!(pairs.get(1), Some("2"));
320
+ /// assert_eq!(pairs.get(2), None);
321
+ /// assert_eq!(pairs.get(55), None);
322
+ /// ```
323
+ pub fn get ( & self , index : usize ) -> Option < & str > {
324
+ if self . size == 0 || index > self . size - 1 {
325
+ return None ;
326
+ }
327
+
328
+ unsafe {
329
+ let string = ffi:: ada_strings_get ( self . strings , index) ;
330
+ let slice = core:: slice:: from_raw_parts ( string. data . cast ( ) , string. length ) ;
331
+ Some ( core:: str:: from_utf8_unchecked ( slice) )
332
+ }
333
+ }
334
+ }
335
+
336
+ impl < ' a > Drop for URLSearchParamsEntry < ' a > {
337
+ /// Automatically frees the underlying C pointer.
338
+ fn drop ( & mut self ) {
339
+ unsafe { ffi:: ada_free_strings ( self . strings ) }
340
+ }
341
+ }
342
+
343
+ #[ cfg( feature = "std" ) ]
344
+ impl < ' a > From < URLSearchParamsEntry < ' a > > for Vec < & ' a str > {
345
+ fn from ( val : URLSearchParamsEntry < ' a > ) -> Self {
346
+ let mut vec = Vec :: with_capacity ( val. size ) ;
347
+ unsafe {
348
+ for index in 0 ..val. size {
349
+ let string = ffi:: ada_strings_get ( val. strings , index) ;
177
350
let slice = core:: slice:: from_raw_parts ( string. data . cast ( ) , string. length ) ;
178
- out . push ( core:: str:: from_utf8_unchecked ( slice) ) ;
351
+ vec . push ( core:: str:: from_utf8_unchecked ( slice) ) ;
179
352
}
180
-
181
- out
182
353
}
354
+ vec
183
355
}
184
356
}
0 commit comments