assert_layout/
lib.rs

1#![doc = include_str!("../README.md")]
2
3mod analyse;
4mod codegen;
5mod lower;
6mod parse;
7
8use self::{analyse::analyse, codegen::codegen, lower::lower, parse::parse};
9use proc_macro::TokenStream;
10use syn::{Error, ItemStruct, Meta, Token, punctuated::Punctuated};
11
12#[proc_macro_attribute]
13pub fn assert_layout(attr: TokenStream, item: TokenStream) -> TokenStream {
14    let attrs = syn::parse_macro_input!(attr with Punctuated<Meta, Token![,]>::parse_terminated);
15    let item = syn::parse_macro_input!(item as ItemStruct);
16    match assert_layout_inner(attrs, item) {
17        Ok(ts) => ts,
18        Err(e) => e.into_compile_error(),
19    }
20    .into()
21}
22
23fn assert_layout_inner(
24    attrs: impl IntoIterator<Item = Meta>,
25    item: ItemStruct,
26) -> Result<proc_macro2::TokenStream, Error> {
27    let ast = parse(attrs, item)?;
28    let model = analyse(ast)?;
29    let ir = lower(model)?;
30    codegen(ir)
31}