use std::marker::PhantomData; macro_rules! try_option { ($expr: expr) => { match $expr { Ok(value) => value, Err(err) => { return Some(Err(err.into())); } } }; } pub(crate) use try_option; macro_rules! or { (($($tt: tt)+) else ($($else_tt: tt)*)) => { $($tt)+ }; (() else ($($else_tt: tt)*)) => { $($else_tt)* }; } pub(crate) use or; macro_rules! builder { ( $(#[doc = $doc: literal])* #[builder( name = $builder_name: ident $(, derives = ($($builder_derive: ident),+))? )] $(#[$attr: meta])* $visibility: vis struct $name: ident { $( $(#[$field_attr: meta])* $field_visibility: vis $field: ident: $field_type: ty, )* } ) => { $(#[doc = $doc])* $(#[$attr])* $visibility struct $name { $( $(#[$field_attr])* $field_visibility $field: $field_type, )* } $(#[derive($($builder_derive),+)])? $visibility struct $builder_name { $( $field: $field_type, )* } impl $builder_name { $( #[must_use] $visibility fn $field(mut self, $field: $field_type) -> Self { self.$field = $field; self } )* #[must_use] $visibility fn build(self) -> $name { $name { $( $field: self.$field, )* } } } impl From<$name> for $builder_name { fn from(built: $name) -> Self { Self { $( $field: built.$field, )* } } } }; } pub(crate) use builder; pub enum RefOrValue<'a, T> { Ref(&'a T), Value(Option), } impl<'a, T> RefOrValue<'a, T> { pub fn get(&self) -> Option<&T> { match self { Self::Ref(val_ref) => Some(val_ref), Self::Value(val_cell) => val_cell.as_ref(), } } } #[derive(Debug)] pub struct Defer<'func, Func, Data> where Func: FnMut(&mut Data) + 'func, { func: Func, pub data: Data, _pd: PhantomData<&'func ()>, } impl<'func, Func, Data> Defer<'func, Func, Data> where Func: FnMut(&mut Data) + 'func, { pub fn new(data: Data, func: Func) -> Self { Self { func, data, _pd: PhantomData } } } impl<'func, Func, Data> Drop for Defer<'func, Func, Data> where Func: FnMut(&mut Data) + 'func, { fn drop(&mut self) { (self.func)(&mut self.data) } } /// Defines a function that will be called at the end of the current scope. /// /// Only captured variables that are later mutably borrowed needs to specified as /// captures. macro_rules! defer { (|$capture: ident| {$($tt: tt)*}) => { // This uses the automatic temporary lifetime extension behaviour introduced // in Rust 1.79.0 (https://blog.rust-lang.org/2024/06/13/Rust-1.79.0.html) to // create a unnamable variable for the Defer struct. The variable should be // unnamable so that it cannot be missused and so that this macro can be used // multiple times without having to give it a identifier for the Defer struct // variable let Defer { data: $capture, .. } = if true { &Defer::new($capture, |$capture| { $($tt)* }) } else { unreachable!(); }; }; } pub(crate) use defer;