[][src]Struct syn::Macro

pub struct Macro {
    pub path: Path,
    pub bang_token: Bang,
    pub delimiter: MacroDelimiter,
    pub tokens: TokenStream,
}

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

This type is available if Syn is built with the "derive" or "full" feature.

Fields

path: Pathbang_token: Bangdelimiter: MacroDelimitertokens: TokenStream

Implementations

impl Macro[src]

pub fn parse_body<T: Parse>(&self) -> Result<T>[src]

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(), "{:?}");
}

pub fn parse_body_with<F: Parser>(&self, parser: F) -> Result<F::Output>[src]

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

Trait Implementations

impl Clone for Macro[src]

impl Debug for Macro[src]

impl Eq for Macro[src]

impl Hash for Macro[src]

impl Parse for Macro[src]

impl PartialEq<Macro> for Macro[src]

impl ToTokens for Macro[src]

Auto Trait Implementations

impl !RefUnwindSafe for Macro

impl !Send for Macro

impl !Sync for Macro

impl Unpin for Macro

impl UnwindSafe for Macro

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Spanned for T where
    T: Spanned + ?Sized
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.