assert_layout 0.0.1

Assert struct layouts, including field sizes and offsets.
Documentation
#![doc = include_str!("../README.md")]

mod analyse;
mod codegen;
mod lower;
mod parse;

use self::{analyse::analyse, codegen::codegen, lower::lower, parse::parse};
use proc_macro::TokenStream;
use syn::{Error, ItemStruct, Meta, Token, punctuated::Punctuated};

#[proc_macro_attribute]
pub fn assert_layout(attr: TokenStream, item: TokenStream) -> TokenStream {
    let attrs = syn::parse_macro_input!(attr with Punctuated<Meta, Token![,]>::parse_terminated);
    let item = syn::parse_macro_input!(item as ItemStruct);
    match assert_layout_inner(attrs, item) {
        Ok(ts) => ts,
        Err(e) => e.into_compile_error(),
    }
    .into()
}

fn assert_layout_inner(
    attrs: impl IntoIterator<Item = Meta>,
    item: ItemStruct,
) -> Result<proc_macro2::TokenStream, Error> {
    let ast = parse(attrs, item)?;
    let model = analyse(ast)?;
    let ir = lower(model)?;
    codegen(ir)
}