parse segments before to_tokens
This commit is contained in:
1 parent
71eaafaa00
commit
f8143a5fc1
1 file changed
+46
-24
+46
-24
@@ -8,11 +8,42 @@ use ::syn::{
|
||||
use proc_macro2::TokenStream;
|
||||
|
||||
pub fn format_args_f_impl(input: IfmtInput) -> Result<TokenStream> {
|
||||
let IfmtInput {
|
||||
format_literal,
|
||||
positional_args,
|
||||
named_args,
|
||||
} = input;
|
||||
|
||||
let named_args = named_args.into_iter().map(|(ident, expr)| {
|
||||
quote! {
|
||||
#ident = #expr
|
||||
}
|
||||
});
|
||||
|
||||
Ok(quote! {
|
||||
format_args!(
|
||||
#format_literal
|
||||
#(, #positional_args)*
|
||||
#(, #named_args)*
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(dead_code)] // dumb compiler does not see the struct being used...
|
||||
#[derive(Debug)]
|
||||
pub struct IfmtInput {
|
||||
pub format_literal: LitStr,
|
||||
pub positional_args: Vec<Expr>,
|
||||
pub named_args: Vec<(Ident, Expr)>,
|
||||
}
|
||||
|
||||
impl IfmtInput {
|
||||
fn parse_segments(self) -> Result<Self> {
|
||||
let IfmtInput {
|
||||
mut format_literal,
|
||||
mut positional_args,
|
||||
mut named_args,
|
||||
} = input;
|
||||
} = self;
|
||||
|
||||
let s = format_literal.value();
|
||||
let out_format_literal = &mut String::with_capacity(s.len());
|
||||
@@ -29,8 +60,7 @@ pub fn format_args_f_impl(input: IfmtInput) -> Result<TokenStream> {
|
||||
out_format_literal.push('{');
|
||||
continue;
|
||||
}
|
||||
let (end, colon_or_closing_brace) =
|
||||
iterator
|
||||
let (end, colon_or_closing_brace) = iterator
|
||||
.find(|&(_, c)| c == '}' || c == ':')
|
||||
.expect(concat!(
|
||||
"Invalid format string literal\n",
|
||||
@@ -56,6 +86,7 @@ pub fn format_args_f_impl(input: IfmtInput) -> Result<TokenStream> {
|
||||
continue;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Segment {
|
||||
Ident(Ident),
|
||||
LitInt(LitInt),
|
||||
@@ -121,32 +152,16 @@ pub fn format_args_f_impl(input: IfmtInput) -> Result<TokenStream> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let named_args = named_args.into_iter().map(|(ident, expr)| {
|
||||
quote! {
|
||||
#ident = #expr
|
||||
}
|
||||
});
|
||||
format_literal = LitStr::new(out_format_literal, format_literal.span());
|
||||
|
||||
Ok(quote! {
|
||||
format_args!(
|
||||
#format_literal
|
||||
#(, #positional_args)*
|
||||
#(, #named_args)*
|
||||
)
|
||||
Ok(Self {
|
||||
format_literal,
|
||||
positional_args,
|
||||
named_args,
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(dead_code)] // dumb compiler does not see the struct being used...
|
||||
pub struct IfmtInput {
|
||||
pub format_literal: LitStr,
|
||||
pub positional_args: Vec<Expr>,
|
||||
pub named_args: Vec<(Ident, Expr)>,
|
||||
}
|
||||
|
||||
impl Parse for IfmtInput {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
fn parse_positional_args(input: ParseStream) -> Result<Self> {
|
||||
let format_literal = input.parse()?;
|
||||
let mut positional_args = vec![];
|
||||
loop {
|
||||
@@ -173,6 +188,7 @@ impl Parse for IfmtInput {
|
||||
})?
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
Ok(Self {
|
||||
format_literal,
|
||||
positional_args,
|
||||
@@ -181,6 +197,12 @@ impl Parse for IfmtInput {
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for IfmtInput {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
Self::parse_positional_args(input).and_then(|new| new.parse_segments())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn defer<'a, T: 'a, Drop: 'a>(x: T, drop: Drop) -> impl ::core::ops::DerefMut<Target = T> + 'a
|
||||
where
|
||||
Drop: FnOnce(T),
|
||||
|
||||
Reference in new issue
Block a user