layout.rs84.21%
1
// Copyright 2024 Google LLC2
//3
// Licensed under the Apache License, Version 2.0 (the "License");4
// you may not use this file except in compliance with the License.5
// You may obtain a copy of the License at6
//7
// https://www.apache.org/licenses/LICENSE-2.08
//9
// Unless required by applicable law or agreed to in writing, software10
// distributed under the License is distributed on an "AS IS" BASIS,11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12
// See the License for the specific language governing permissions and13
// limitations under the License.14
15
use proc_macro::TokenStream;16
use quote::{format_ident, quote};17
use syn::{DeriveInput, parse_macro_input};18
19
pub fn derive_layout(input: TokenStream) -> TokenStream {74x20
let input = parse_macro_input!(input as DeriveInput);74x21
let syn::Data::Struct(ref data) = input.data else {74x22
panic!()23
};24
let syn::Fields::Named(ref fields) = data.fields else {74x25
panic!()26
};27
let name = input.ident;74x28
let layout_consts = fields.named.iter().map(|field| {516x29
let Some(ref field_ident) = field.ident else {516x30
panic!()31
};32
let type_ = &field.ty;516x33
let ident_upper = field_ident.to_string().to_uppercase();516x34
let const_field_size = format_ident!("SIZE_{}", ident_upper);516x35
let const_field_offset = format_ident!("OFFSET_{}", ident_upper);516x36
let const_field_layout = format_ident!("LAYOUT_{}", ident_upper);516x37
quote!(516x38
pub const #const_field_size: usize = ::core::mem::size_of::<#type_>();39
pub const #const_field_offset: usize = ::core::mem::offset_of!(#name, #field_ident);40
pub const #const_field_layout: (usize, usize) = (Self::#const_field_offset, Self::#const_field_size);41
)42
});516x43
TokenStream::from(quote!(74x44
impl #name {45
#(#layout_consts)*46
}47
))48
}74x49