]> git.proxmox.com Git - proxmox.git/blob - proxmox-lang/src/lib.rs
add proxmox-lang crate
[proxmox.git] / proxmox-lang / src / lib.rs
1 //! Rust language related helpers.
2 //!
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.
6
7 mod constnamedbitmap;
8
9 pub mod ops;
10
11 /// Macro to write error-handling blocks (like perl eval {})
12 ///
13 /// #### Example:
14 /// ```
15 /// # use proxmox_lang::try_block;
16 /// # macro_rules! format_err {
17 /// # ($($msg:tt)+) => { format!($($msg)+) }
18 /// # }
19 /// # macro_rules! bail {
20 /// # ($($msg:tt)+) => { return Err(format_err!($($msg)+)); }
21 /// # }
22 /// # let some_condition = false;
23 /// let result = try_block!({
24 /// if (some_condition) {
25 /// bail!("some error");
26 /// }
27 /// Ok(())
28 /// })
29 /// .map_err(|e| format_err!("my try block returned an error - {}", e));
30 /// ```
31
32 #[macro_export]
33 macro_rules! try_block {
34 { $($token:tt)* } => {{ (|| -> Result<_,_> { $($token)* })() }}
35 }
36
37 /// Statically assert the size of a type at compile time.
38 ///
39 /// This should compile:
40 /// ```
41 /// # use proxmox_lang::static_assert_size;
42 /// #[repr(C)]
43 /// struct Stuff {
44 /// value: [u8; 32]
45 /// }
46 /// static_assert_size!(Stuff, 32);
47 /// ```
48 ///
49 /// This should fail to compile:
50 /// ```compile_fail
51 /// # use proxmox_lang::static_assert_size;
52 /// #[repr(C)]
53 /// struct Stuff {
54 /// value: [u8; 32]
55 /// }
56 /// static_assert_size!(Stuff, 128);
57 /// ```
58 #[macro_export]
59 macro_rules! static_assert_size {
60 ($ty:ty, $size:expr) => {
61 const _: fn() -> () = || {
62 let _ = ::std::mem::transmute::<[u8; $size], $ty>;
63 };
64 };
65 }
66
67 /// Evaluates to the offset (in bytes) of a given member within a struct
68 ///
69 /// ```
70 /// # use proxmox_lang::offsetof;
71 ///
72 /// #[repr(C)]
73 /// struct Stuff {
74 /// first: u32,
75 /// second: u32,
76 /// }
77 ///
78 /// assert_eq!(offsetof!(Stuff, second), 4);
79 ///
80 /// ```
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.
83 //
84 // So with 1.56, do this instead:
85 //
86 // unsafe { &(std::mem::transmute::<_, &$ty>(0usize).$field) as *const _ as usize }
87 #[macro_export]
88 macro_rules! offsetof {
89 ($ty:ty, $field:ident) => {
90 unsafe { &(*(std::ptr::null::<$ty>())).$field as *const _ as usize }
91 };
92 }