1616use encoding:: EncodingOverride ;
1717use percent_encoding:: { percent_encode_byte, percent_decode} ;
1818use std:: borrow:: { Borrow , Cow } ;
19+ use std:: fmt;
1920use std:: str;
2021
2122
@@ -216,6 +217,15 @@ pub struct Serializer<T: Target> {
216217 target : Option < T > ,
217218 start_position : usize ,
218219 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+ }
219229}
220230
221231pub trait Target {
@@ -272,6 +282,7 @@ impl<T: Target> Serializer<T> {
272282 target : Some ( target) ,
273283 start_position : start_position,
274284 encoding : EncodingOverride :: utf8 ( ) ,
285+ custom_encoding : None ,
275286 }
276287 }
277288
@@ -290,11 +301,20 @@ impl<T: Target> Serializer<T> {
290301 self
291302 }
292303
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+
293312 /// Serialize and append a name/value pair.
294313 ///
295314 /// Panics if called after `.finish()`.
296315 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) ;
298318 self
299319 }
300320
@@ -311,7 +331,8 @@ impl<T: Target> Serializer<T> {
311331 let string = string ( & mut self . target ) ;
312332 for pair in iter {
313333 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 ( ) ) ;
315336 }
316337 }
317338 self
@@ -324,6 +345,8 @@ impl<T: Target> Serializer<T> {
324345 /// Panics if called after `.finish()`.
325346 #[ cfg( feature = "query_encoding" ) ]
326347 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()" ) ;
327350 {
328351 let string = string ( & mut self . target ) ;
329352 append_separator_if_needed ( string, self . start_position ) ;
@@ -361,9 +384,20 @@ fn string<T: Target>(target: &mut Option<T>) -> &mut String {
361384}
362385
363386fn append_pair ( string : & mut String , start_position : usize , encoding : EncodingOverride ,
387+ custom_encoding : & mut Option < SilentDebug < Box < FnMut ( & str ) -> Cow < [ u8 ] > > > > ,
364388 name : & str , value : & str ) {
365389 append_separator_if_needed ( string, start_position) ;
366- string . extend ( byte_serialize ( & encoding . encode ( name. into ( ) ) ) ) ;
390+ append_encoded ( name, string , encoding , custom_encoding ) ;
367391 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) ) ;
369403}
0 commit comments