This commit is contained in:
nora 2022-09-24 22:05:13 +02:00
parent 010126ce0b
commit 8862186a1f
7 changed files with 65 additions and 31 deletions

View file

@ -5,7 +5,7 @@ use std::cell::Cell;
use format::Parse as _; use format::Parse as _;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use quote::{ToTokens, quote}; use quote::{quote, ToTokens};
use syn::{ use syn::{
parse::{Parse, ParseStream}, parse::{Parse, ParseStream},
parse_macro_input, Expr, ExprAssign, ExprPath, Ident, LitStr, PathArguments, Result, Token, parse_macro_input, Expr, ExprAssign, ExprPath, Ident, LitStr, PathArguments, Result, Token,
@ -77,7 +77,9 @@ fn format_args_impl(input: Input) -> syn::Result<TokenStream> {
let current_position = Cell::new(0); let current_position = Cell::new(0);
Ok(Scoped::new(&input, &fmt_parts, &current_position).to_token_stream().into()) Ok(Scoped::new(&input, &fmt_parts, &current_position)
.to_token_stream()
.into())
} }
#[proc_macro] #[proc_macro]

View file

@ -5,7 +5,8 @@ use quote::{quote, ToTokens};
use crate::{ use crate::{
format::{ format::{
Align, Count, Format, FormatArg, FormatArgRef, FormatTrait, FormatterArgs, Piece, Sign, Align, Count, DebugHex, Format, FormatArg, FormatArgRef, FormatTrait, FormatterArgs, Piece,
Sign,
}, },
Input, Input,
}; };
@ -148,6 +149,14 @@ fn opt_value_tokens(scope: Scoped<'_, FormatterArgs<'_>>) -> TokenStream {
opts = quote! { #prefix::WithSignAwareZeroPad(#opts) }; opts = quote! { #prefix::WithSignAwareZeroPad(#opts) };
} }
if let Some(DebugHex::Lower) = args.debug_hex {
opts = quote! { #prefix::WithDebugLowerHex(#opts) };
}
if let Some(DebugHex::Upper) = args.debug_hex {
opts = quote! { #prefix::WithDebugUpperHex(#opts) };
}
opts opts
} }
@ -197,6 +206,14 @@ fn opt_ty_tokens(scope: Scoped<'_, FormatterArgs<'_>>) -> TokenStream {
opts = quote! { #prefix::WithSignAwareZeroPad<#opts> }; opts = quote! { #prefix::WithSignAwareZeroPad<#opts> };
} }
if let Some(DebugHex::Lower) = args.debug_hex {
opts = quote! { #prefix::WithDebugLowerHex<#opts> };
}
if let Some(DebugHex::Upper) = args.debug_hex {
opts = quote! { #prefix::WithDebugUpperHex<#opts> };
}
opts opts
} }

View file

@ -64,7 +64,9 @@ impl<W, O: FmtOpts> Formatter<W, O> {
} }
} }
// BUILDERS /////////////////////////////////////////
////////////// BUILDERS /////////////////
/////////////////////////////////////////
// adapted from `core` // adapted from `core`
use crate as fmt; use crate as fmt;

View file

@ -121,4 +121,10 @@ mod tests {
let result = format!("a: {}", 32523532u64); let result = format!("a: {}", 32523532u64);
assert_eq!(result, "a: 32523532"); assert_eq!(result, "a: 32523532");
} }
#[test]
fn escape() {
let result = format!("a: {{{}}}", 6);
assert_eq!(result, "a: {6}");
}
} }

View file

@ -40,13 +40,12 @@ mod pointers {
} }
} }
impl<T: ?Sized> Pointer for &T { impl<T: ?Sized> Pointer for &T {
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result { fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result {
Pointer::fmt(&(*self as *const T), f) Pointer::fmt(&(*self as *const T), f)
} }
} }
impl<T: ?Sized> Pointer for &mut T { impl<T: ?Sized> Pointer for &mut T {
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result { fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result {
Pointer::fmt(&(&**self as *const T), f) Pointer::fmt(&(&**self as *const T), f)
@ -57,6 +56,11 @@ mod pointers {
ptr_addr: usize, ptr_addr: usize,
f: &mut Formatter<W, O>, f: &mut Formatter<W, O>,
) -> Result { ) -> Result {
fn tail<W: Write, O: FmtOpts>(f: &mut Formatter<W, O>, ptr_addr: usize) -> Result {
let mut f = f.wrap_with(&crate::opts::WithAlternate(()));
LowerHex::fmt(&ptr_addr, &mut f)
}
// The alternate flag is already treated by LowerHex as being special- // The alternate flag is already treated by LowerHex as being special-
// it denotes whether to prefix with 0x. We use it to work out whether // it denotes whether to prefix with 0x. We use it to work out whether
// or not to zero extend, and then unconditionally set it to get the // or not to zero extend, and then unconditionally set it to get the
@ -69,22 +73,13 @@ mod pointers {
let mut f = f.wrap_with(&crate::opts::WithWidth::<(), WIDTH>(())); let mut f = f.wrap_with(&crate::opts::WithWidth::<(), WIDTH>(()));
let mut f = f.wrap_with(&crate::opts::WithAlternate(())); tail(&mut f, ptr_addr)
let ret = LowerHex::fmt(&ptr_addr, &mut f); } else {
tail(&mut f, ptr_addr)
return ret;
} }
} else {
let mut f = f.wrap_with(&crate::opts::WithAlternate(())); tail(f, ptr_addr)
let ret = LowerHex::fmt(&ptr_addr, &mut f);
return ret;
} }
let mut f = f.wrap_with(&crate::opts::WithAlternate(()));
let ret = LowerHex::fmt(&ptr_addr, &mut f);
ret
} }
} }

View file

@ -247,13 +247,13 @@ impl<W: Write, O: FmtOpts> Formatter<W, O> {
&mut self, &mut self,
padding: usize, padding: usize,
default: Alignment, default: Alignment,
actual_fill: char, self_fill: char,
actual_align: Alignment, self_align: Alignment,
) -> std::result::Result<PostPadding, Error> { ) -> std::result::Result<PostPadding, Error> {
// WARN: We might have `self` in an invalid state, don't touch `self` opts // WARN: We might have `self` in an invalid state, don't touch `self` opts
let align = match actual_align { let align = match self_align {
Alignment::Unknown => default, Alignment::Unknown => default,
_ => actual_align, _ => self_align,
}; };
let (pre_pad, post_pad) = match align { let (pre_pad, post_pad) = match align {
@ -263,10 +263,10 @@ impl<W: Write, O: FmtOpts> Formatter<W, O> {
}; };
for _ in 0..pre_pad { for _ in 0..pre_pad {
self.buf.write_char(actual_fill)?; self.buf.write_char(self_fill)?;
} }
Ok(PostPadding::new(actual_fill, post_pad)) Ok(PostPadding::new(self_fill, post_pad))
} }
fn write_formatted_parts(&mut self, formatted: &numfmt::Formatted<'_>) -> Result { fn write_formatted_parts(&mut self, formatted: &numfmt::Formatted<'_>) -> Result {
@ -355,7 +355,7 @@ impl<W: Write, O: FmtOpts> Formatter<W, O> {
else { else {
let align = Alignment::Left; let align = Alignment::Left;
let post_padding = let post_padding =
self.padding(width - chars_count, Alignment::Right, self.fill(), align)?; self.padding(width - chars_count, align, self.fill(), self.align())?;
self.buf.write_str(s)?; self.buf.write_str(s)?;
post_padding.write(self) post_padding.write(self)
} }

View file

@ -115,14 +115,23 @@ fn test_format_int_exp_limits() {
assert_eq!(format!("{:e}", i32::MAX), "2.147483647e9"); assert_eq!(format!("{:e}", i32::MAX), "2.147483647e9");
assert_eq!(format!("{:e}", i64::MIN), "-9.223372036854775808e18"); assert_eq!(format!("{:e}", i64::MIN), "-9.223372036854775808e18");
assert_eq!(format!("{:e}", i64::MAX), "9.223372036854775807e18"); assert_eq!(format!("{:e}", i64::MAX), "9.223372036854775807e18");
assert_eq!(format!("{:e}", i128::MIN), "-1.70141183460469231731687303715884105728e38"); assert_eq!(
assert_eq!(format!("{:e}", i128::MAX), "1.70141183460469231731687303715884105727e38"); format!("{:e}", i128::MIN),
"-1.70141183460469231731687303715884105728e38"
);
assert_eq!(
format!("{:e}", i128::MAX),
"1.70141183460469231731687303715884105727e38"
);
assert_eq!(format!("{:e}", u8::MAX), "2.55e2"); assert_eq!(format!("{:e}", u8::MAX), "2.55e2");
assert_eq!(format!("{:e}", u16::MAX), "6.5535e4"); assert_eq!(format!("{:e}", u16::MAX), "6.5535e4");
assert_eq!(format!("{:e}", u32::MAX), "4.294967295e9"); assert_eq!(format!("{:e}", u32::MAX), "4.294967295e9");
assert_eq!(format!("{:e}", u64::MAX), "1.8446744073709551615e19"); assert_eq!(format!("{:e}", u64::MAX), "1.8446744073709551615e19");
assert_eq!(format!("{:e}", u128::MAX), "3.40282366920938463463374607431768211455e38"); assert_eq!(
format!("{:e}", u128::MAX),
"3.40282366920938463463374607431768211455e38"
);
} }
#[test] #[test]
@ -132,7 +141,10 @@ fn test_format_int_exp_precision() {
assert_eq!(format!("{:.10e}", i16::MIN), "-3.2768000000e4"); assert_eq!(format!("{:.10e}", i16::MIN), "-3.2768000000e4");
assert_eq!(format!("{:.10e}", i32::MIN), "-2.1474836480e9"); assert_eq!(format!("{:.10e}", i32::MIN), "-2.1474836480e9");
assert_eq!(format!("{:.20e}", i64::MIN), "-9.22337203685477580800e18"); assert_eq!(format!("{:.20e}", i64::MIN), "-9.22337203685477580800e18");
assert_eq!(format!("{:.40e}", i128::MIN), "-1.7014118346046923173168730371588410572800e38"); assert_eq!(
format!("{:.40e}", i128::MIN),
"-1.7014118346046923173168730371588410572800e38"
);
//test rounding //test rounding
assert_eq!(format!("{:.1e}", i8::MIN), "-1.3e2"); assert_eq!(format!("{:.1e}", i8::MIN), "-1.3e2");