Struct Macro

struct Macro { ... }

A macro invocation: println!("{}", mac).

Fields

path: Path
bang_token: Not
delimiter: MacroDelimiter
tokens: TokenStream

Implementations

impl Macro

fn parse_body<T: Parse>(self: &Self) -> Result<T>

Parse the tokens within the macro invocation's delimiters into a syntax tree.

This is equivalent to syn::parse2::<T>(mac.tokens) except that it produces a more useful span when tokens is empty.

Example

use syn::{parse_quote, Expr, ExprLit, Ident, Lit, LitStr, Macro, Token};
use syn::ext::IdentExt;
use syn::parse::{Error, Parse, ParseStream, Result};
use syn::punctuated::Punctuated;

// The arguments expected by libcore's format_args macro, and as a
// result most other formatting and printing macros like println.
//
//     println!("{} is {number:.prec$}", "x", prec=5, number=0.01)
struct FormatArgs {
    format_string: Expr,
    positional_args: Vec<Expr>,
    named_args: Vec<(Ident, Expr)>,
}

impl Parse for FormatArgs {
    fn parse(input: ParseStream) -> Result<Self> {
        let format_string: Expr;
        let mut positional_args = Vec::new();
        let mut named_args = Vec::new();

        format_string = input.parse()?;
        while !input.is_empty() {
            input.parse::<Token![,]>()?;
            if input.is_empty() {
                break;
            }
            if input.peek(Ident::peek_any) && input.peek2(Token![=]) {
                while !input.is_empty() {
                    let name: Ident = input.call(Ident::parse_any)?;
                    input.parse::<Token![=]>()?;
                    let value: Expr = input.parse()?;
                    named_args.push((name, value));
                    if input.is_empty() {
                        break;
                    }
                    input.parse::<Token![,]>()?;
                }
                break;
            }
            positional_args.push(input.parse()?);
        }

        Ok(FormatArgs {
            format_string,
            positional_args,
            named_args,
        })
    }
}

// Extract the first argument, the format string literal, from an
// invocation of a formatting or printing macro.
fn get_format_string(m: &Macro) -> Result<LitStr> {
    let args: FormatArgs = m.parse_body()?;
    match args.format_string {
        Expr::Lit(ExprLit { lit: Lit::Str(lit), .. }) => Ok(lit),
        other => {
            // First argument was not a string literal expression.
            // Maybe something like: println!(concat!(...), ...)
            Err(Error::new_spanned(other, "format string must be a string literal"))
        }
    }
}

fn main() {
    let invocation = parse_quote! {
        println!("{:?}", Instant::now())
    };
    let lit = get_format_string(&invocation).unwrap();
    assert_eq!(lit.value(), "{:?}");
}
fn parse_body_with<F: Parser>(self: &Self, parser: F) -> Result<<F as >::Output>

Parse the tokens within the macro invocation's delimiters using the given parser.

impl Clone for Macro

fn clone(self: &Self) -> Self

impl Debug for Macro

fn fmt(self: &Self, formatter: &mut Formatter<'_>) -> Result

impl Eq for Macro

impl Freeze for Macro

impl Hash for Macro

fn hash<H>(self: &Self, state: &mut H)
where
    H: Hasher

impl Parse for Macro

fn parse(input: ParseStream<'_>) -> Result<Self>

impl PartialEq for Macro

fn eq(self: &Self, other: &Self) -> bool

impl RefUnwindSafe for Macro

impl Send for Macro

impl Sync for Macro

impl ToTokens for Macro

fn to_tokens(self: &Self, tokens: &mut TokenStream)

impl Unpin for Macro

impl UnsafeUnpin for Macro

impl UnwindSafe for Macro

impl<T> Any for Macro

fn type_id(self: &Self) -> TypeId

impl<T> Borrow for Macro

fn borrow(self: &Self) -> &T

impl<T> BorrowMut for Macro

fn borrow_mut(self: &mut Self) -> &mut T

impl<T> CloneToUninit for Macro

unsafe fn clone_to_uninit(self: &Self, dest: *mut u8)

impl<T> From for Macro

fn from(t: T) -> T

Returns the argument unchanged.

impl<T> Spanned for Macro

fn span(self: &Self) -> Span

impl<T> ToOwned for Macro

fn to_owned(self: &Self) -> T
fn clone_into(self: &Self, target: &mut T)

impl<T, U> Into for Macro

fn into(self: Self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

impl<T, U> TryFrom for Macro

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

impl<T, U> TryInto for Macro

fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error>