1#![doc = include_str!("../README.md")]
2
3use std::fmt::Display;
4
5pub use layout_macro::Layout;
6
7#[derive(Debug)]
8pub struct LayoutInfo {
9 pub name: &'static str,
11 pub size: usize,
14 pub align: usize,
15 pub fields: Vec<Field>,
16}
17
18impl LayoutInfo {
19 pub fn new(name: &'static str, size: usize, align: usize, fields: Vec<Field>) -> Self {
20 Self {
21 name,
22 size,
24 align,
25 fields
26 }
27 }
28}
29
30#[derive(Debug)]
31pub struct Field {
32 pub name: &'static str,
33 pub offset: usize,
34 pub layout: LayoutInfo,
35}
36
37pub trait Layout {
38 fn get_layout() -> LayoutInfo;
39}
40
41#[macro_export]
42macro_rules! offset_of_struct {
43 ($struct_name: ty, $field_name: tt) => {
44 {
45 let p = 0 as *const $struct_name;
47 unsafe {&(*p).$field_name as *const _ as usize}
48 }
49 };
50}
51
52impl Display for LayoutInfo {
53 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54 f.write_fmt(format_args!("{} (size: {}, align: {})\n", self.name, self.size, self.align))?;
55
56 let name_width = 8;
57 let offset_width = 6;
58 let size_width = 6;
59 let ty_width = 10;
60
61 f.write_fmt(format_args!("| {:^name_width$} | {:^offset_width$} | {:^size_width$} | {:^ty_width$} |\n", "field", "offset", "size", "type"))?;
63 f.write_fmt(format_args!("| {:-<name_width$} | {:-<offset_width$} | {:-<size_width$} | {:-<ty_width$} |\n",
65 "-",
66 "-",
67 "-",
68 "-",
69 ))?;
70
71 for field in self.fields.iter() {
72 f.write_fmt(format_args!("| {:<name_width$} | {:<offset_width$} | {:<size_width$} | {:<ty_width$} |\n",
73 field.name,
74 field.offset,
75 field.layout.size,
76 format!("{} (align: {})",
77 field.layout.name,
78 field.layout.align,),
79 ))?;
80 }
81 f.write_fmt(format_args!(""))
82 }
83}