align_data/lib.rs
1/*!
2Simply increase the alignment of any statics or `include_bytes!`.
3*/
4
5#![no_std]
6
7/// Helper which enforces that its given `T` is aligned to at least the requested alignment of `A`.
8///
9/// If the alignment of `A` is lower than the required alignment of `T` then its alignment is used instead.
10#[repr(C)]
11pub struct Aligned<A, T: ?Sized>(pub [A; 0], pub T);
12
13/// Align to 16 bytes.
14#[repr(align(16))]
15pub struct Align16;
16
17/// Align to 32 bytes.
18#[repr(align(32))]
19pub struct Align32;
20
21/// Align to 64 bytes.
22#[repr(align(64))]
23pub struct Align64;
24
25/// Align to 128 bytes.
26#[repr(align(128))]
27pub struct Align128;
28
29/// Align to 256 bytes.
30#[repr(align(256))]
31pub struct Align256;
32
33/// Align to 512 bytes.
34#[repr(align(512))]
35pub struct Align512;
36
37/// Align to 4KiB.
38#[repr(align(0x1000))]
39pub struct Align4K;
40
41/// Returns a static reference of the expression `$e` with requested alignment.
42///
43/// Unfortunately it is required to specify the type of the expression `$e` because it is stored in a `static`.
44///
45/// # Examples
46///
47/// ```
48/// use align_data::{aligned, Align16};
49///
50/// let five = aligned!(Align16, i32, 5);
51/// assert_eq!(five as *const _ as usize % 0x10, 0);
52/// ```
53#[macro_export]
54macro_rules! aligned {
55 ($align:ty, $e_ty:ty, $e:expr) => {{
56 static ALIGNED: &'static $crate::Aligned<$align, $e_ty> = &$crate::Aligned([], $e);
57 &ALIGNED.1
58 }};
59}
60
61/// Includes bytes with given alignment.
62///
63/// This macro ensures that the bytes included by `include_bytes!` is properly aligned.
64///
65/// # Examples
66///
67/// ```
68/// use align_data::{include_aligned, Align4K};
69///
70/// static ALIGNED: &[u8] = include_aligned!(Align4K, "lib.rs");
71/// assert_eq!(ALIGNED.as_ptr() as usize % 0x1000, 0);
72/// ```
73#[macro_export]
74macro_rules! include_aligned {
75 ($align:ty, $file:expr) => {{
76 static ALIGNED: &'static $crate::Aligned<$align, [u8; include_bytes!($file).len()]> = &$crate::Aligned([], *include_bytes!($file));
77 &ALIGNED.1
78 }};
79}
80
81/// Transmutes the included bytes.
82///
83/// This macro ensures that the resulting instance is aligned properly.
84///
85/// # Examples
86///
87/// ```
88/// use align_data::include_transmute;
89///
90/// static DATA: [u32; 3] = unsafe { include_transmute!("../tests/data.txt") };
91/// assert_eq!(DATA[0], u32::from_ne_bytes([b'A'; 4]));
92/// ```
93///
94/// # Safety
95///
96/// This macro simply transmutes the included byte array to its destination type.
97/// It is your responsibility to ensure that this transmutation is correct.
98#[macro_export]
99macro_rules! include_transmute {
100 ($file:expr) => {
101 ::core::mem::transmute(*include_bytes!($file))
102 };
103}