16
16
use encoding:: EncodingOverride ;
17
17
use percent_encoding:: { percent_encode_byte, percent_decode} ;
18
18
use std:: borrow:: { Borrow , Cow } ;
19
+ use std:: fmt;
19
20
use std:: str;
20
21
21
22
@@ -216,6 +217,15 @@ pub struct Serializer<T: Target> {
216
217
target : Option < T > ,
217
218
start_position : usize ,
218
219
encoding : EncodingOverride ,
220
+ custom_encoding : Option < SilentDebug < Box < FnMut ( & str ) -> Cow < [ u8 ] > > > > ,
221
+ }
222
+
223
+ struct SilentDebug < T > ( T ) ;
224
+
225
+ impl < T > fmt:: Debug for SilentDebug < T > {
226
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
227
+ f. write_str ( "…" )
228
+ }
219
229
}
220
230
221
231
pub trait Target {
@@ -272,6 +282,7 @@ impl<T: Target> Serializer<T> {
272
282
target : Some ( target) ,
273
283
start_position : start_position,
274
284
encoding : EncodingOverride :: utf8 ( ) ,
285
+ custom_encoding : None ,
275
286
}
276
287
}
277
288
@@ -290,11 +301,20 @@ impl<T: Target> Serializer<T> {
290
301
self
291
302
}
292
303
304
+ /// Set the character encoding to be used for names and values before percent-encoding.
305
+ pub fn custom_encoding_override < F > ( & mut self , encode : F ) -> & mut Self
306
+ where F : FnMut ( & str ) -> Cow < [ u8 ] > + ' static
307
+ {
308
+ self . custom_encoding = Some ( SilentDebug ( Box :: new ( encode) ) ) ;
309
+ self
310
+ }
311
+
293
312
/// Serialize and append a name/value pair.
294
313
///
295
314
/// Panics if called after `.finish()`.
296
315
pub fn append_pair ( & mut self , name : & str , value : & str ) -> & mut Self {
297
- append_pair ( string ( & mut self . target ) , self . start_position , self . encoding , name, value) ;
316
+ append_pair ( string ( & mut self . target ) , self . start_position , self . encoding ,
317
+ & mut self . custom_encoding , name, value) ;
298
318
self
299
319
}
300
320
@@ -311,7 +331,8 @@ impl<T: Target> Serializer<T> {
311
331
let string = string ( & mut self . target ) ;
312
332
for pair in iter {
313
333
let & ( ref k, ref v) = pair. borrow ( ) ;
314
- append_pair ( string, self . start_position , self . encoding , k. as_ref ( ) , v. as_ref ( ) ) ;
334
+ append_pair ( string, self . start_position , self . encoding ,
335
+ & mut self . custom_encoding , k. as_ref ( ) , v. as_ref ( ) ) ;
315
336
}
316
337
}
317
338
self
@@ -324,6 +345,8 @@ impl<T: Target> Serializer<T> {
324
345
/// Panics if called after `.finish()`.
325
346
#[ cfg( feature = "query_encoding" ) ]
326
347
pub fn append_charset ( & mut self ) -> & mut Self {
348
+ assert ! ( self . custom_encoding. is_none( ) ,
349
+ "Cannot use both custom_encoding_override() and append_charset()" ) ;
327
350
{
328
351
let string = string ( & mut self . target ) ;
329
352
append_separator_if_needed ( string, self . start_position ) ;
@@ -361,9 +384,20 @@ fn string<T: Target>(target: &mut Option<T>) -> &mut String {
361
384
}
362
385
363
386
fn append_pair ( string : & mut String , start_position : usize , encoding : EncodingOverride ,
387
+ custom_encoding : & mut Option < SilentDebug < Box < FnMut ( & str ) -> Cow < [ u8 ] > > > > ,
364
388
name : & str , value : & str ) {
365
389
append_separator_if_needed ( string, start_position) ;
366
- string . extend ( byte_serialize ( & encoding . encode ( name. into ( ) ) ) ) ;
390
+ append_encoded ( name, string , encoding , custom_encoding ) ;
367
391
string. push ( '=' ) ;
368
- string. extend ( byte_serialize ( & encoding. encode ( value. into ( ) ) ) ) ;
392
+ append_encoded ( value, string, encoding, custom_encoding) ;
393
+ }
394
+
395
+ fn append_encoded ( s : & str , string : & mut String , encoding : EncodingOverride ,
396
+ custom_encoding : & mut Option < SilentDebug < Box < FnMut ( & str ) -> Cow < [ u8 ] > > > > ) {
397
+ let bytes = if let Some ( SilentDebug ( ref mut custom) ) = * custom_encoding {
398
+ custom ( s)
399
+ } else {
400
+ encoding. encode ( s. into ( ) )
401
+ } ;
402
+ string. extend ( byte_serialize ( & bytes) ) ;
369
403
}
0 commit comments