nom_derive_impl/lib.rs
1//! # nom-derive-impl
2//!
3//! ## Overview
4//!
5//! nom-derive is a custom derive attribute, to derive `nom` parsers automatically from the structure definition.
6//!
7//! This crate is not meant to be used directly.
8//! See [`nom-derive`](https://docs.rs/nom-derive) crate for documentation.
9
10extern crate proc_macro;
11extern crate proc_macro2;
12extern crate syn;
13#[macro_use]
14extern crate quote;
15
16use proc_macro::TokenStream;
17use syn::*;
18
19mod config;
20mod endian;
21mod enums;
22mod gen;
23mod meta;
24mod parsertree;
25mod structs;
26
27use crate::endian::*;
28use crate::gen::*;
29
30/// The `Nom` derive automatically generates a `parse` function for the structure
31/// using [nom] parsers. It will try to infer parsers for primitive of known
32/// types, but also allows you to specify parsers using custom attributes.
33///
34/// Deriving parsers supports `struct` and `enum` types.
35///
36/// The documentation of the `Nom` custom derive attribute and all possible options
37/// can be found in the [nom-derive documentation](https://docs.rs/nom-derive).
38///
39/// Many examples are provided, and more can be found in the [project
40/// tests](https://github.com/rust-bakery/nom-derive/tree/master/tests).
41///
42/// [nom]: https://github.com/Geal/nom
43#[proc_macro_derive(Nom, attributes(nom))]
44pub fn nom(input: TokenStream) -> TokenStream {
45 // Parse the input tokens into a syntax tree
46 let ast = parse_macro_input!(input as DeriveInput);
47
48 // Build and return the generated impl
49 match gen_impl(&ast, ParserEndianness::Unspecified) {
50 Ok(ts) => ts.into(),
51 Err(e) => e.to_compile_error().into(),
52 }
53}
54
55/// The `NomBE` acts like the [`Nom`] attribute, but sets the endianness to big-endian for the
56/// current object. This can be overriden locally at the field-level.
57#[proc_macro_derive(NomBE, attributes(nom))]
58pub fn nom_be(input: TokenStream) -> TokenStream {
59 // Parse the input tokens into a syntax tree
60 let ast = parse_macro_input!(input as DeriveInput);
61
62 // Build and return the generated impl
63 match gen_impl(&ast, ParserEndianness::BigEndian) {
64 Ok(ts) => ts.into(),
65 Err(e) => e.to_compile_error().into(),
66 }
67}
68
69/// The `NomLE` acts like the [`Nom`] attribute, but sets the endianness to little-endian for the
70/// current object. This can be overriden locally at the field-level.
71#[proc_macro_derive(NomLE, attributes(nom))]
72pub fn nom_le(input: TokenStream) -> TokenStream {
73 // Parse the input tokens into a syntax tree
74 let ast = parse_macro_input!(input as DeriveInput);
75
76 // Build and return the generated impl
77 match gen_impl(&ast, ParserEndianness::LittleEndian) {
78 Ok(ts) => ts.into(),
79 Err(e) => e.to_compile_error().into(),
80 }
81}