1111//! - `number` enables `x`, `X`, `b`, `o`, `e` and `E` trait specifiers
1212//! - `pointer` enables `p` trait specifiers
1313#![ warn( clippy:: pedantic, missing_docs) ]
14- #![ allow( clippy:: return_self_not_must_use, clippy:: wildcard_imports, clippy:: implicit_hasher) ]
14+ #![ allow(
15+ clippy:: return_self_not_must_use,
16+ clippy:: wildcard_imports,
17+ clippy:: implicit_hasher
18+ ) ]
1519#![ cfg_attr( docsrs, feature( doc_auto_cfg) ) ]
1620use std:: borrow:: Borrow ;
1721use std:: collections:: HashMap ;
@@ -263,23 +267,23 @@ enum TraitSpec {
263267 #[ cfg( feature = "debug" ) ]
264268 Question ,
265269 #[ cfg( feature = "debug" ) ]
266- xQuestion ,
270+ LowerHexQuestion ,
267271 #[ cfg( feature = "debug" ) ]
268- XQuestion ,
272+ UpperHexQuestion ,
269273 #[ cfg( feature = "number" ) ]
270- x ,
274+ LowerHex ,
271275 #[ cfg( feature = "number" ) ]
272- X ,
276+ UpperHex ,
273277 #[ cfg( feature = "number" ) ]
274- b ,
278+ Binary ,
275279 #[ cfg( feature = "number" ) ]
276- o ,
280+ Octal ,
277281 #[ cfg( feature = "number" ) ]
278- e ,
282+ LowerExp ,
279283 #[ cfg( feature = "number" ) ]
280- E ,
284+ UpperExp ,
281285 #[ cfg( feature = "pointer" ) ]
282- p ,
286+ Pointer ,
283287}
284288
285289impl TraitSpec {
@@ -295,7 +299,7 @@ impl TraitSpec {
295299 #[ cfg( feature = "debug" ) ]
296300 b'x' if format. as_bytes ( ) [ 1 ] == b'?' => {
297301 step ( 1 , format, idx) ;
298- Ok ( TraitSpec :: xQuestion )
302+ Ok ( TraitSpec :: LowerHexQuestion )
299303 }
300304 #[ cfg( not( feature = "debug" ) ) ]
301305 b'x' if format. as_bytes ( ) [ 1 ] == b'?' => {
@@ -304,38 +308,38 @@ impl TraitSpec {
304308 #[ cfg( feature = "debug" ) ]
305309 b'X' if format. as_bytes ( ) [ 1 ] == b'?' => {
306310 step ( 1 , format, idx) ;
307- Ok ( TraitSpec :: XQuestion )
311+ Ok ( TraitSpec :: UpperHexQuestion )
308312 }
309313 #[ cfg( not( feature = "debug" ) ) ]
310314 b'X' if format. as_bytes ( ) [ 1 ] == b'?' => {
311315 Err ( Error :: UnsupportedOption ( "X?" , "debug" , * idx) )
312316 }
313317 #[ cfg( feature = "number" ) ]
314- b'o' => Ok ( TraitSpec :: o ) ,
318+ b'o' => Ok ( TraitSpec :: Octal ) ,
315319 #[ cfg( not( feature = "number" ) ) ]
316320 b'o' => Err ( Error :: UnsupportedOption ( "o" , "number" , * idx) ) ,
317321 #[ cfg( feature = "number" ) ]
318- b'x' => Ok ( TraitSpec :: x ) ,
322+ b'x' => Ok ( TraitSpec :: LowerHex ) ,
319323 #[ cfg( not( feature = "number" ) ) ]
320324 b'x' => Err ( Error :: UnsupportedOption ( "x" , "number" , * idx) ) ,
321325 #[ cfg( feature = "number" ) ]
322- b'X' => Ok ( TraitSpec :: X ) ,
326+ b'X' => Ok ( TraitSpec :: UpperHex ) ,
323327 #[ cfg( not( feature = "number" ) ) ]
324328 b'X' => Err ( Error :: UnsupportedOption ( "X" , "number" , * idx) ) ,
325329 #[ cfg( feature = "number" ) ]
326- b'b' => Ok ( TraitSpec :: b ) ,
330+ b'b' => Ok ( TraitSpec :: Binary ) ,
327331 #[ cfg( not( feature = "number" ) ) ]
328332 b'b' => Err ( Error :: UnsupportedOption ( "b" , "number" , * idx) ) ,
329333 #[ cfg( feature = "number" ) ]
330- b'e' => Ok ( TraitSpec :: e ) ,
334+ b'e' => Ok ( TraitSpec :: LowerExp ) ,
331335 #[ cfg( not( feature = "number" ) ) ]
332336 b'e' => Err ( Error :: UnsupportedOption ( "e" , "number" , * idx) ) ,
333337 #[ cfg( feature = "number" ) ]
334- b'E' => Ok ( TraitSpec :: E ) ,
338+ b'E' => Ok ( TraitSpec :: UpperExp ) ,
335339 #[ cfg( not( feature = "number" ) ) ]
336340 b'E' => Err ( Error :: UnsupportedOption ( "E" , "number" , * idx) ) ,
337341 #[ cfg( feature = "pointer" ) ]
338- b'p' => Ok ( TraitSpec :: p ) ,
342+ b'p' => Ok ( TraitSpec :: Pointer ) ,
339343 #[ cfg( not( feature = "pointer" ) ) ]
340344 b'p' => Err ( Error :: UnsupportedOption ( "p" , "pointer" , * idx) ) ,
341345 _ => Err ( FormatArgumentError :: ExpectedBrace ( * idx) . into ( ) ) ,
@@ -350,7 +354,6 @@ impl TraitSpec {
350354#[ derive( Default , Debug ) ]
351355struct FormatArgument < ' a > {
352356 ident : & ' a str ,
353- fill : Option < char > ,
354357 alignment : Alignment ,
355358 sign : Sign ,
356359 hash : bool ,
@@ -376,6 +379,8 @@ pub enum FormatArgumentError {
376379 InvalidWidth ( ParseIntError , usize ) ,
377380 /// Unable to parse specified precision as usize
378381 InvalidPrecision ( ParseIntError , usize ) ,
382+ /// Fill is not supported due to [rust-lang/rfcs#3394](https://github.com/rust-lang/rfcs/pull/3394)
383+ Fill ( usize ) ,
379384}
380385
381386impl Display for FormatArgumentError {
@@ -391,6 +396,10 @@ impl Display for FormatArgumentError {
391396 FormatArgumentError :: InvalidPrecision ( e, idx) => {
392397 write ! ( f, "Unable to parse precision at {idx} as usize: {e}" )
393398 }
399+ FormatArgumentError :: Fill ( idx) => write ! (
400+ f,
401+ "Fill is not supported due to https://github.com/rust-lang/rfcs/pull/3394 at {idx}"
402+ ) ,
394403 }
395404 }
396405}
@@ -423,10 +432,8 @@ impl<'a> FormatArgument<'a> {
423432 if format[ fill. len_utf8 ( ) ..] . is_empty ( ) {
424433 return Ok ( it) ;
425434 }
426- if let Some ( alignment) = alignment ( format[ fill. len_utf8 ( ) ..] . as_bytes ( ) [ 0 ] ) {
427- it. fill = Some ( fill) ;
428- it. alignment = alignment;
429- step ( 1 + fill. len_utf8 ( ) , format, idx) ;
435+ if alignment ( format[ fill. len_utf8 ( ) ..] . as_bytes ( ) [ 0 ] ) . is_some ( ) {
436+ return Err ( FormatArgumentError :: Fill ( * idx) . into ( ) ) ;
430437 } else if fill. is_ascii ( ) {
431438 if let Some ( alignment) = alignment ( fill as u8 ) {
432439 it. alignment = alignment;
@@ -529,7 +536,6 @@ pub fn format<K: Borrow<str> + Eq + Hash>(
529536 let start = * idx;
530537 let FormatArgument {
531538 ident,
532- fill,
533539 alignment,
534540 sign,
535541 hash,
@@ -541,36 +547,9 @@ pub fn format<K: Borrow<str> + Eq + Hash>(
541547 let value = context
542548 . get ( ident)
543549 . ok_or ( Error :: MissingValue ( ident. to_string ( ) , start) ) ?;
544- if fill. is_some ( ) {
545- unimplemented ! ( "fill is not supported" ) ;
546- // let mut tmp = String::new();
547- // format_value(
548- // &mut tmp, value, 0, precision, alignment, sign, hash,
549- // zero, trait_, )?;
550- // if tmp.len() < width {
551- // let fill = &fill.to_string();
552- // let width = width - tmp.len();
553- // if alignment == Alignment::Right {
554- // out.push_str(&fill.repeat(width))
555- // }
556- // if alignment == Alignment::Center {
557- // out.push_str(&fill.repeat(width / 2))
558- // }
559- // out.push_str(&tmp);
560- // if alignment == Alignment::Center {
561- // out.push_str(&fill.repeat(width - width / 2))
562- // }
563- // if alignment == Alignment::Left {
564- // out.push_str(&fill.repeat(width))
565- // }
566- // } else {
567- // out.push_str(&tmp);
568- // }
569- } else {
570- format_value (
571- & mut out, value, width, precision, alignment, sign, hash, zero, trait_, * idx,
572- ) ?;
573- }
550+ format_value (
551+ & mut out, value, width, precision, alignment, sign, hash, zero, trait_, * idx,
552+ ) ?;
574553 ensure ! (
575554 format. starts_with( '}' ) ,
576555 FormatArgumentError :: ExpectedBrace ( * idx) . into( )
@@ -587,34 +566,3 @@ pub fn format<K: Borrow<str> + Eq + Hash>(
587566 }
588567 Ok ( out)
589568}
590-
591- #[ test]
592- fn test_format ( ) {
593- // let p = &42;
594- // assert_eq!(
595- // format(
596- // "{ident:a>+09.15}",
597- // [("ident", Formattable::from(&"hi"))].into_iter().collect(),
598- // )
599- // .unwrap(),
600- // format!("{ident:a>+09.15}", ident = "hi")
601- // );
602- assert_eq ! (
603- format( "{{hello}}" , & HashMap :: <String , Formattable >:: new( ) ) . unwrap( ) ,
604- "{hello}"
605- ) ;
606- // assert_eq!(
607- // format(
608- // "{hi:10} {hi:?} {int:#x?} {int:b} {int:#X} {int:4o} {display}
609- // {display:5} {display:05}", &[
610- // ("hi", Formattable::debug_display(&"hello")),
611- // ("int", Formattable::integer(&123u8)),
612- // ("display", (&10).into())
613- // ]
614- // .into_iter()
615- // .collect()
616- // )
617- // .unwrap(),
618- // r#"hello "hello" 0x7b 1111011 0x7B 173 10 10 00010"#
619- // );
620- }
0 commit comments