[][src]Crate serde_syn

serde_syn is a serde backend for parsing Rust syntax inside procedural macros. For example, you can deserialize parameters for a custom derive out of attributes and directly into structs. The goal is to eliminate the parsing boilerplate that goes into writing procedural macros.

The interface to serde_syn is fairly minimal. Here are a few ways to use it:

Lots of pre-made configurations exist inside the config module for common syntaxes (JSON-like, attribute-like, expression-like, etc) or you can combine flags to build your own.

Example derive implementation

Here you can see a simple derive macro implementation. For more examples, see the examples directory.

/// The format of `named` attributes.
#[derive(Deserialize)]
struct Props {
    rename: Option<String>, // #[named(rename="hello")]
    lowercase: Option<()>,  // #[named(lowercase)]
}

#[proc_macro_derive(NamedType, attributes(named))]
pub fn my_macro(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let mut name = input.ident.to_string();

    for attr in input.attrs.iter().filter(|a| a.path.is_ident("named")) {
        let parser = parser::<Props>(config::RUSTY_META);
        let props = match attr.parse_args_with(parser) {
            Ok(props) => props,
            Err(err) => return err.to_compile_error().into(),
        };

        if let Some(rename) = props.rename { name = rename; }
        if props.lowercase.is_some() { name = name.to_lowercase(); }
    }

    let ident = &input.ident;
    (quote! {
        impl NamedType for #ident {
            fn name() -> &'static str { #name }
        }
    }).into()
}

Error handling

Deserialization errors are automatically assigned a "span" (the area of the source code that could not be parsed) before being returned from parser and from_stream as ordinary syn::Errors. When that error is reported to the Rust compiler, the correct regions of code will be highlighted:

error: unknown field `lowrcase`, expected `rename` or `lowercase`
  --> named_type.rs:4:13
   |
4  |     #[named(lowrcase)]
   |             ^^^^^^^^

If you use Deserializer directly, serde_syn will do its best to assign a span but it is always possible to create an error with no span using serde's required custom function.

Limitations

serde_syn is early in development and so still has some gotchyas. For example, serde_syn will throw an error if you try to deserialize into a serde_json Value since it doesn't yet support self-description.

If you find any bugs, have any ideas, or wind up with free time to help random open source projects, please drop by the repository.

Re-exports

pub use config::Config;

Modules

config

Configure serde_syn to parse different styles of syntax.

Structs

Deserializer

A generic structure that deserializes tokens from Syn into Rust values.

Enums

Error

A serde deserialization error which wraps syn::Error or a custom string. The Syn variant is preferred when possible, since it tracks the location in the input syntax where the error occurred.

Traits

Tokens

An implementor of this trait can borrow or own a syn::ParseBuffer.

Functions

from_stream

Deserialize the type T from Rust syntax. This will almost always be used from inside a Parse implementation. To deserialize a token stream or string, consider using parser.

parser

Create a Syn Parser which can deserialize the type T from a token stream or string.

Type Definitions

BufferDeserializer

A Deserializer from Syn token buffers into Rust values.

StreamDeserializer

A Deserializer from Syn token streams into Rust values.