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}