from_tokenstream_spanned

Function from_tokenstream_spanned 

Source
pub fn from_tokenstream_spanned<'a, T>(
    span: &DelimSpan,
    tokens: &'a TokenStream,
) -> Result<T>
where T: Deserialize<'a>,
Expand description

Deserialize an instance of type T from a TokenStream with data inside, along with a DelimSpan for the surrounding braces.

This is useful when parsing an attribute nested inside an outer macro. In that case, better span information (not just Span::call_site) can be produced.

§Example

The most common use is with syn::MetaList instances. For example, if your macro is #[derive(Record)] and you’re invoked like this:

#[derive(Record)]
#[record { worker = "Homer J. Simpson", floor = 7, region = "G" }]
fn test() {}

Then, the record attribute inside can be interpreted as a syn::MetaList. With it in hand:

use syn::parse_quote;
use serde::Deserialize;
use serde_tokenstream::from_tokenstream_spanned;
use serde_tokenstream::Result;

fn main() -> Result<()> {
    #[derive(Deserialize)]
    struct Record {
        worker: String,
        floor: u32,
        region: String,
    }

    // This is the `syn::MetaList` instance above.
    let list: syn::MetaList = parse_quote! {
        record {
            worker = "Homer J. Simpson",
            floor = 7,
            region = "G",
        }
    };

    let rec = from_tokenstream_spanned::<Record>(list.delimiter.span(), &list.tokens)?;
    println!("{} {}{}", rec.worker, rec.floor, rec.region);
    Ok(())
}

If there’s an error like a missing field, it will now be reported with the span of the braces inside the record attribute (whereas from_tokenstream lacks the necessary Span information).