1 //! Rust language related helpers.
3 //! This provides some macros for features which are not yet available in the language, or
4 //! sometimes also types from nightly `std` which are simple enough to do just haven't been
5 //! bikeshedded and stabilized in the standard library yet.
11 /// Macro to write error-handling blocks (like perl eval {})
15 /// # use proxmox_lang::try_block;
16 /// # macro_rules! format_err {
17 /// # ($($msg:tt)+) => { format!($($msg)+) }
19 /// # macro_rules! bail {
20 /// # ($($msg:tt)+) => { return Err(format_err!($($msg)+)); }
22 /// # let some_condition = false;
23 /// let result = try_block!({
24 /// if (some_condition) {
25 /// bail!("some error");
29 /// .map_err(|e| format_err!("my try block returned an error - {}", e));
33 macro_rules
! try_block
{
34 { $($token:tt)* }
=> {{ (|| -> Result<_,_> { $($token)* }
)() }}
37 /// Statically assert the size of a type at compile time.
39 /// This should compile:
41 /// # use proxmox_lang::static_assert_size;
46 /// static_assert_size!(Stuff, 32);
49 /// This should fail to compile:
51 /// # use proxmox_lang::static_assert_size;
56 /// static_assert_size!(Stuff, 128);
59 macro_rules
! static_assert_size
{
60 ($ty
:ty
, $size
:expr
) => {
61 const _
: fn() -> () = || {
62 let _
= ::std
::mem
::transmute
::<[u8; $size
], $ty
>;
67 /// Evaluates to the offset (in bytes) of a given member within a struct
70 /// # use proxmox_lang::offsetof;
78 /// assert_eq!(offsetof!(Stuff, second), 4);
81 // FIXME: With 1.56 we get `const transmute` which may help making this usable `const fn` as we can
82 // avoid dereferencing the raw pointer by transmuting `0usize` into a proper reference instead.
84 // So with 1.56, do this instead:
86 // unsafe { &(std::mem::transmute::<_, &$ty>(0usize).$field) as *const _ as usize }
88 macro_rules
! offsetof {
89 ($ty
:ty
, $field
:ident
) => {
90 unsafe { &(*(std::ptr::null::<$ty>())).$field as *const _ as usize }