layout_internal 0.2.0

Internal implementation crate for layout
Documentation
#![warn(clippy::all, clippy::pedantic)]
#![allow(clippy::needless_return, clippy::redundant_field_names)]
#![allow(clippy::use_self, clippy::too_many_lines, clippy::missing_panics_doc)]
#![allow(clippy::uninlined_format_args)]

extern crate proc_macro;

use proc_macro2::TokenStream;
use quote::TokenStreamExt;

mod index;
#[macro_use]
mod input;
mod compact_repr;
mod generic;
mod iter;
mod ptr;
mod refs;
mod slice;
mod soa_impl;
mod vec;

pub(crate) mod names;

#[proc_macro_derive(SOA, attributes(layout, soa_attr, nested_soa))]
pub fn layout(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let ast = syn::parse(input).expect("Failed to parse derive macro for SOA");
    let input = input::Input::new(ast);

    let mut generated = TokenStream::new();
    generated.append_all(vec::derive(&input));
    generated.append_all(refs::derive(&input));
    generated.append_all(ptr::derive(&input));
    generated.append_all(slice::derive(&input));
    generated.append_all(slice::derive_mut(&input));
    generated.append_all(index::derive(&input));
    generated.append_all(iter::derive(&input));
    generated.append_all(derive_trait(&input));

    generated.append_all(generic::derive_slice(&input));
    generated.append_all(generic::derive_slice_mut(&input));
    generated.append_all(generic::derive_vec(&input));
    generated.into()
}

use quote::quote;

use crate::input::Input;

fn derive_trait(input: &Input) -> TokenStream {
    let name = &input.name;
    let vec_name = names::vec_name(name);

    quote! {
        impl layout::SOA for #name {
            type Type = #vec_name;
        }
    }
}

#[allow(clippy::used_underscore_binding)]
#[proc_macro_attribute]
pub fn soa_impl(
    _attr: proc_macro::TokenStream,
    item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
    soa_impl::soa_impl_transform(item)
}

#[proc_macro_derive(CompactRepr)]
pub fn compact_repr(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let ast = syn::parse(input)
        .expect("Failed to parse derive macro for CompactRepr");
    compact_repr::derive_compact_repr(&ast).into()
}