lunar-lib 0.12.0

Common utilities for lunar applications
Documentation
#[macro_export]
macro_rules! command {
(
    $(#[$attr:meta])*
    $vis:vis $msg_enum:ident => {
        $(requests {
            $(
                $request_fn:ident($($field:ident : $ty:ty),*) -> $ret:ty;
            )*
        })?
        $(events {
            $(
                $event_fn:ident($($event_field:ident : $event_ty:ty),*);
            )*
        })?
    }
) => {
        paste::paste! {
            $(#[$attr])*
            $vis enum $msg_enum {
                $($(
                    [<$request_fn:camel>] { $($field: $ty,)* callback: tokio::sync::oneshot::Sender<$ret> },
                )*)?
                $($(
                    [<$event_fn:camel>] { $($event_field: $event_ty,)* },
                )*)?
            }

            impl std::fmt::Debug for $msg_enum {
                fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                    match self {
                        $($(
                            Self::[<$request_fn:camel>] { .. } => {
                                write!(f, stringify!([<$request_fn:camel>]))
                            }
                        )*)?
                        $($(
                            Self::[<$event_fn:camel>] { .. } => {
                                write!(f, stringify!([<$event_fn:camel>]))
                            }
                        )*)?
                    }
                }
            }

            impl $msg_enum {
                $($(
                    $vis fn [<$request_fn>]($($field : $ty),*) -> (Self, tokio::sync::oneshot::Receiver<$ret>) {
                        let (tx, rx) = tokio::sync::oneshot::channel();
                        (
                            Self::[<$request_fn:camel>] {
                                $($field,)*
                                callback: tx,
                            },
                            rx
                        )
                    }
                )*)?

                $($(
                    $vis fn [<$event_fn>]($($event_field : $event_ty),*) -> Self {
                        Self::[<$event_fn:camel>] {
                            $($event_field,)*
                        }
                    }
                )*)?
            }
        }
    };
}

pub fn spawn_background_thread<F1, F2, T>(f: F1, on_return: Option<F2>)
where
    F1: FnOnce() -> T + Send + 'static,
    F2: FnOnce(T) + Send + 'static,
{
    std::thread::spawn(move || {
        if let Some(on_return) = on_return {
            on_return(f());
        } else {
            f();
        }
    });
}