#![deny(
missing_docs,
missing_debug_implementations,
missing_copy_implementations,
elided_lifetimes_in_paths,
rust_2018_idioms,
clippy::fallible_impl_from,
clippy::missing_const_for_fn
)]
#![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/55122894")]
use atomic::Atomic;
use std::{future::Future, sync::atomic::Ordering};
pub use ffi::ZeroCopyBuffer;
pub use into_dart::{IntoDart, IntoDartExceptPrimitive};
mod dart_array;
mod into_dart;
mod into_dart_extra;
#[cfg(feature = "catch-unwind")]
mod catch_unwind;
#[cfg(feature = "chrono")]
mod chrono;
#[cfg(feature = "uuid")]
mod uuid;
pub mod ffi;
static POST_COBJECT: Atomic<Option<ffi::DartPostCObjectFnType>> =
Atomic::new(None);
#[no_mangle]
pub unsafe extern "C" fn store_dart_post_cobject(
ptr: ffi::DartPostCObjectFnType,
) {
POST_COBJECT.store(Some(ptr), Ordering::Relaxed);
}
#[derive(Copy, Clone, Debug)]
pub struct Isolate {
port: i64,
}
impl Isolate {
pub const fn new(port: i64) -> Self {
Self { port }
}
pub fn post(&self, msg: impl IntoDart) -> bool {
if let Some(func) = POST_COBJECT.load(Ordering::Relaxed) {
unsafe {
let mut msg = msg.into_dart();
let result = func(self.port, &mut msg);
if !result {
ffi::run_destructors(&msg);
}
result
}
} else {
false
}
}
pub async fn task<T, R>(self, t: T) -> bool
where
T: Future<Output = R> + Send + 'static,
R: Send + IntoDart + 'static,
{
self.post(t.await)
}
#[cfg(feature = "catch-unwind")]
pub async fn catch_unwind<T, R>(
self,
t: T,
) -> Result<bool, Box<dyn std::any::Any + Send>>
where
T: Future<Output = R> + Send + 'static,
R: Send + IntoDart + 'static,
{
catch_unwind::CatchUnwind::new(t)
.await
.map(|msg| Ok(self.post(msg)))?
}
}