pub use crate::ffi::*;
pub use crate::into_into_dart::IntoIntoDart;
use std::marker::PhantomData;
#[derive(Clone)]
pub struct Rust2Dart {
pub(crate) channel: Channel,
}
#[derive(Debug)]
pub enum Rust2DartAction {
Success = 0,
Error = 1,
CloseStream = 2,
Panic = 3,
}
impl From<&crate::handler::Error> for Rust2DartAction {
fn from(value: &crate::handler::Error) -> Self {
match value {
crate::handler::Error::CustomError(_) => Self::Error,
crate::handler::Error::Panic(_) => Self::Panic,
}
}
}
impl IntoDart for Rust2DartAction {
fn into_dart(self) -> DartAbi {
(self as i32).into_dart()
}
}
impl Rust2Dart {
pub fn new(port: MessagePort) -> Self {
Rust2Dart {
channel: Channel::new(port),
}
}
pub fn success(&self, result: impl IntoDart) -> bool {
self.channel.post(vec![
Rust2DartAction::Success.into_dart(),
result.into_dart(),
])
}
pub fn panic(&self, e: impl IntoDart) -> bool {
self.channel
.post(vec![Rust2DartAction::Panic.into_dart(), e.into_dart()])
}
pub fn error(&self, e: impl IntoDart) -> bool {
self.channel
.post(vec![Rust2DartAction::Error.into_dart(), e.into_dart()])
}
pub fn close_stream(&self) -> bool {
self.channel
.post(vec![Rust2DartAction::CloseStream.into_dart()])
}
}
pub struct TaskCallback {
rust2dart: Rust2Dart,
}
impl TaskCallback {
pub fn new(rust2dart: Rust2Dart) -> Self {
Self { rust2dart }
}
pub fn stream_sink<T, D>(&self) -> StreamSink<T>
where
T: IntoIntoDart<D>,
D: IntoDart,
{
StreamSink::new(self.rust2dart.clone())
}
}
#[derive(Clone)]
pub struct ChannelHandle(pub String);
impl ChannelHandle {
#[cfg(wasm)]
pub fn port(&self) -> MessagePort {
PortLike::broadcast(&self.0)
}
}
#[derive(Clone)]
pub struct StreamSink<T> {
#[cfg(not(wasm))]
rust2dart: Rust2Dart,
#[cfg(wasm)]
handle: ChannelHandle,
_phantom_data: PhantomData<T>,
}
impl<T> StreamSink<T> {
pub fn new(rust2dart: Rust2Dart) -> Self {
#[cfg(wasm)]
let name = rust2dart
.channel
.broadcast_name()
.expect("Not a BroadcastChannel");
Self {
#[cfg(not(wasm))]
rust2dart,
#[cfg(wasm)]
handle: ChannelHandle(name),
_phantom_data: PhantomData,
}
}
fn rust2dart(&self) -> Rust2Dart {
#[cfg(not(wasm))]
return self.rust2dart.clone();
#[cfg(wasm)]
Rust2Dart::new(self.handle.port())
}
pub fn add<D: IntoDart>(&self, value: T) -> bool
where
T: IntoIntoDart<D>,
{
self.rust2dart().success(value.into_into_dart().into_dart())
}
pub fn close(&self) -> bool {
self.rust2dart().close_stream()
}
}
pub trait BoxIntoDart {
fn box_into_dart(self: Box<Self>) -> DartAbi;
}
impl<T: IntoDart> BoxIntoDart for T {
fn box_into_dart(self: Box<T>) -> DartAbi {
self.into_dart()
}
}