pub use crate::pod::PlainOldData;
#[cfg(feature = "smol")]
pub use async_io;
use crate::entry;
use std::sync::atomic::{AtomicBool, Ordering};
pub static INITIALIZED: AtomicBool = AtomicBool::new(false);
pub(crate) fn perform_sanity_checks() {
assert!(
INITIALIZED.load(Ordering::Acquire),
"#[crossmist::main] or a call to crossmist::init() is missing"
);
}
pub trait Report {
fn report(self) -> i32;
}
impl Report for () {
fn report(self) -> i32 {
0
}
}
impl<T, E: std::fmt::Debug> Report for Result<T, E> {
fn report(self) -> i32 {
match self {
Ok(_) => 0,
Err(e) => {
eprintln!("Error: {e:?}");
1
}
}
}
}
pub type Identity<'a, T> = <T as IdentityImpl<'a>>::Type;
pub trait IdentityImpl<'a> {
type Type: ?Sized;
}
impl<T: ?Sized> IdentityImpl<'_> for T {
type Type = Self;
}
macro_rules! implements {
($type:ty: $($trait:tt)*) => {{
#[allow(dead_code)]
fn use_trait<T: $($trait)*>(_: T) {}
struct Probe<'a, T: ?Sized>(&'a std::cell::Cell<bool>, std::marker::PhantomData<T>);
impl<T: ?Sized> Clone for Probe<'_, T> {
fn clone(&self) -> Self {
self.0.set(false);
Self(self.0, self.1)
}
}
impl<T: $($trait)*> Copy for Probe<'_, T> {}
let cell = std::cell::Cell::new(true);
let _ = [Probe(&cell, std::marker::PhantomData::<$type>)].clone();
cell.get()
}};
}
pub(crate) use implements;
pub fn if_void<T>() -> Option<T> {
implements!(T: IsVoid).then(|| unsafe { std::ptr::NonNull::<T>::dangling().as_ptr().read() })
}
trait IsVoid {}
impl IsVoid for () {}
pub fn init() {
if INITIALIZED.swap(true, Ordering::AcqRel) {
return;
}
let mut args = std::env::args();
if let Some(s) = args.next() {
if s == "_crossmist_" {
entry::crossmist_main(args);
}
}
entry::start_root();
}
#[cfg(feature = "tokio")]
#[doc(hidden)]
#[macro_export]
macro_rules! if_tokio {
($($a:tt)*) => { $($a)* };
}
#[cfg(not(feature = "tokio"))]
#[doc(hidden)]
#[macro_export]
macro_rules! if_tokio {
($($a:tt)*) => {};
}
#[cfg(feature = "smol")]
#[doc(hidden)]
#[macro_export]
macro_rules! if_smol {
($($a:tt)*) => { $($a)* };
}
#[cfg(not(feature = "smol"))]
#[doc(hidden)]
#[macro_export]
macro_rules! if_smol {
($($a:tt)*) => {};
}