Skip to main content

Crate typed_quote

Crate typed_quote 

Source
Expand description

§typed-quote

github docs.rs docs.rs Crates.io MSRV build status

A fully typed quote!() alternative for both proc-macro and proc-macro2.

§Quick start

§Output TokenStream

typed_quote::quote!(...) returns a fully typed value that implements IntoTokens, ToTokens, WithSpan, IntoTokenTree or ToTokenTree depending on the quoted content.

use typed_quote::prelude::*;

let crate_name = quote!("typed-quote");
let tokens = quote!(hello #crate_name !);

let ts: proc_macro2::TokenStream = tokens.into_token_stream2();

assert_eq!(ts.to_string(), r#"hello "typed-quote" !"#);

§Set span

  • Call ts.with_default_span(span) to specify a span only for un-spanned tokens in ts.

    • quote!(un-spanned).with_default_span(span) will specify span for all tokens.
    • quote!(#quoted_var).with_default_span(span) will call quoted_var.with_default_span(span).
    • proc_macro::TokenStream::from_str("...").unwrap().with_default_span(span) will not change span because proc_macro::TokenStream already has a span.
  • Call ts.with_replaced_span(span) to set span for all tokens in ts.

§Comparison with ::quote

typed_quote::typed_quote!() is an alias of typed_quote::quote!() so you can disambiguate typed_quote!() from quote::quote!().

  • typed_quote is new, not well tested, and will contain breaking changes in the future. You should use ::quote for production.

  • ::quote::quote!() returns a proc_macro2::TokenStream.

    typed_quote!() returns a fully typed struct that implements IntoTokens and you can decide to output proc_macro::TokenStream or proc_macro2::TokenStream.

  • ::quote has quote_spanned!(span => ...).

    But in typed_quote, use typed_quote!(...).with_default_span(span) instead.

  • ::quote::quote!(#var) only references &var but typed_quote!(#var) moves var. Since &impl ToTokens implements both IntoToken and Copy, let var = &var; typed_quote!(#var) will work if var is a value of impl ToTokens.

  • ::quote::ToTokens is dyn-

§cargo features

  • alloc (default)

    This feature implements traits for Box, Rc.

    This library is no_std and only alloc is enabled by default.

  • proc-macro and proc-macro2

    Enable one or both of these features if necessary:

    cargo add typed-quote --features proc-macro
    cargo add typed-quote --features proc-macro2
    cargo add typed-quote --features proc-macro,proc-macro2

    You don’t need to enable them when you’re writing a library that just inputs/outputs tokens. Users of your library can decide which feature to enable and call the corresponding into_token_stream or into_token_stream2.

    cargo add typed-quote
    use typed_quote::prelude::*;
    
    fn braced(stream: impl IntoTokens) -> impl IntoTokenTree {
        quote!({ stream })
    }

§Cheat sheet

Typederived Traitsvalue examples

Never

Into/ToTokenTree

Into/ToTokens

(Ref)WithSpan

Either<A, B>

Into/ToTokenTree

Into/ToTokens

(Ref)WithSpan

if condition {
    Either::A(quote!(a))
} else {
    Either::B(quote!(b))
}

Option<T>

Into/ToTokens

(Ref)WithSpan

if condition {
    Some(quote!(some))
} else {
    None
}

&T

Into/ToTokens where T: ToTokens

(Ref)WithSpan where T: RefWithSpan

&quote!(ref)

Box<T: ?Sized>

Into/ToTokenTree

Into/ToTokens

Box::new(quote!(_))
Box::new(quote!(_)) as Box<dyn ToTokenTree>

Rc<T: ?Sized>

Into/ToTokenTree where T: ToTokenTree

Into/ToTokens where T: ToTokens

Rc::new(quote!(_))
Rc::new(quote!(_)) as Rc<dyn ToTokenTree>

Empty

Into/ToTokens

(Ref)WithSpan

quote!()

grouped token stream:

{...}

[...]

(...)

Into/ToTokens

(Ref)WithSpan

quote!( { braced tokens } )
quote!( [ 0, 1, 2, 3, 4 ] )
quote!( ( #tokens )       )

ConstIdent<T: ?Sized + HasConstIdent>

Ident<'_>

Into/ToTokenTree

Into/ToTokens

(Ref)WithSpan

quote!(my_ident)
quote!(my_ident).as_ident()

ConstLifetime<T: ?Sized + HasConstLifetime>

Lifetime<'_>

Into/ToTokens

(Ref)WithSpan

quote!('my_lifetime)
quote!('my_lifetime).as_lifetime()

ConstLiteral<T: ?Sized + HasConstLiteral>

Literal<'_>

Into/ToTokenTree

Into/ToTokens

(Ref)WithSpan

quote!("my literal")
quote!("my literal").as_literal()

Concat<A, B>

Into/ToTokens

(Ref)WithSpan

let a = quote!(a);
let b = quote!(b);
quote!(#a #b)

IterTokens<I: IntoIterator>

IntoTokens where I::Item: IntoTokens

ToTokens where I::Item: IntoTokens, I: Clone

WithSpan where I::Item: WithSpan

RefWithSpan where I::Item: WithSpan, I: Clone

IterTokens([quote!(a); 10])

punctuation

Into/ToTokenTree

Into/ToTokens

(Ref)WithSpan

quote!( : )
quote!( . )
quote!( * )

punctuations

Into/ToTokens

(Ref)WithSpan

quote!( :: )
quote!( .. )
quote!( *= )

proc_macro(2)::{   TokenTree(2),   Group(2),   Ident(2),   Punct(2),   Literal(2), }

Into/ToTokenTree

Into/ToTokens

(Ref)WithSpan

proc_macro::Ident::new(
    "tt",
    proc_macro::Span::call_site()
)

proc_macro(2)::TokenStream(2)

Into/ToTokens

(Ref)WithSpan

proc_macro::TokenStream::new()

Re-exports§

pub use quote as typed_quote;

Modules§

maybe_span
prelude
tokens

Macros§

quote
quote_token

Enums§

Either
Never

Traits§

IntoTokenTree
Into a token tree.
IntoTokens
Into token stream.
RefWithSpan
To tokens with new span.
Span
A proc_macro::Span or proc_macro2::Span.
ToTokenTree
To a token tree.
ToTokens
To token stream.
WithSpan
Into tokens with new span.