layout_lib/
lib.rs

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    /// type name
10    pub name: &'static str,
11    // todo: type id
12    // pub id: std::any::TypeId,
13    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            // id,
23            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: *const $struct_name = std::ptr::null();
46            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        // center-aligned
62        f.write_fmt(format_args!("| {:^name_width$} | {:^offset_width$} | {:^size_width$} | {:^ty_width$} |\n", "field", "offset", "size", "type"))?;
63        // left-aligned. if the value being formatted is smaller than width, then '-' will be printed
64        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}