basic tracing implemented

This commit is contained in:
Rowan S-L 2022-05-27 19:27:24 -04:00
parent 016f144c73
commit 8b27cbea81
7 changed files with 510 additions and 68 deletions

359
Cargo.lock generated
View File

@ -2,6 +2,32 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]]
name = "anyhow"
version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
[[package]]
name = "async-recursion"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cda8f4bcc10624c4e85bc66b3f452cca98cfa5ca002dc83a16aad2367641bea"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "async-trait"
version = "0.1.53"
@ -13,18 +39,41 @@ dependencies = [
"syn",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bumpalo"
version = "3.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
[[package]]
name = "bytes"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
[[package]]
name = "cfg-if"
version = "1.0.0"
@ -43,6 +92,49 @@ dependencies = [
"unique-type",
]
[[package]]
name = "dabus-test"
version = "0.0.0"
dependencies = [
"anyhow",
"async-recursion",
"async-trait",
"dabus",
"derivative",
"flume",
"futures",
"log",
"pretty_env_logger",
"thiserror",
"tokio",
"unique-type",
"uuid",
]
[[package]]
name = "derivative"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "env_logger"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
dependencies = [
"atty",
"humantime",
"log",
"regex",
"termcolor",
]
[[package]]
name = "flume"
version = "0.10.12"
@ -154,10 +246,28 @@ dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi",
"wasi 0.10.2+wasi-snapshot-preview1",
"wasm-bindgen",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "humantime"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
dependencies = [
"quick-error",
]
[[package]]
name = "js-sys"
version = "0.3.57"
@ -204,6 +314,18 @@ version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "mio"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799"
dependencies = [
"libc",
"log",
"wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys",
]
[[package]]
name = "nanorand"
version = "0.7.0"
@ -213,6 +335,45 @@ dependencies = [
"getrandom",
]
[[package]]
name = "num_cpus"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "once_cell"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
[[package]]
name = "parking_lot"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-sys",
]
[[package]]
name = "pin-project"
version = "1.0.10"
@ -245,6 +406,16 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pretty_env_logger"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d"
dependencies = [
"env_logger",
"log",
]
[[package]]
name = "proc-macro2"
version = "1.0.37"
@ -254,6 +425,12 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "quick-error"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]]
name = "quote"
version = "1.0.18"
@ -263,18 +440,69 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "signal-hook-registry"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
dependencies = [
"libc",
]
[[package]]
name = "slab"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
[[package]]
name = "smallvec"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
[[package]]
name = "socket2"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "spin"
version = "0.9.3"
@ -295,6 +523,15 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "termcolor"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
dependencies = [
"winapi-util",
]
[[package]]
name = "thiserror"
version = "1.0.31"
@ -315,6 +552,37 @@ dependencies = [
"syn",
]
[[package]]
name = "tokio"
version = "1.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4903bf0427cf68dddd5aa6a93220756f8be0c34fcfa9f5e6191e103e15a31395"
dependencies = [
"bytes",
"libc",
"memchr",
"mio",
"num_cpus",
"once_cell",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"tokio-macros",
"winapi",
]
[[package]]
name = "tokio-macros"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-xid"
version = "0.2.2"
@ -327,12 +595,27 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65276803d5c0b9aeb522fffd31e97ec312a60344f6d345dfa640e809038c740f"
[[package]]
name = "uuid"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93bbc61e655a4833cf400d0d15bf3649313422fa7572886ad6dab16d79886365"
dependencies = [
"getrandom",
]
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.80"
@ -386,3 +669,77 @@ name = "wasm-bindgen-shared"
version = "0.2.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
dependencies = [
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
[[package]]
name = "windows_i686_gnu"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
[[package]]
name = "windows_i686_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
[[package]]
name = "windows_x86_64_gnu"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
[[package]]
name = "windows_x86_64_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"

View File

@ -2,5 +2,6 @@
[workspace]
members = [
"dabus",
"dabus-test",
]
resolver = "2"

View File

@ -17,8 +17,6 @@ async fn asmain() -> Result<()> {
let mut bus = DABus::new();
bus.register(Printer::new());
bus.register(HelloHandler);
bus.fire(PRINT_EVENT, "Hello, World!".to_string()).await?;
bus.fire(FLUSH_EVENT, ()).await?;
bus.fire(HELLO_EVENT, ()).await?;
Ok(())
}

View File

@ -1,4 +1,8 @@
#[derive(Debug, thiserror::Error)]
use std::any::type_name;
use crate::{EventDef, util::dyn_debug::DynDebug};
#[derive(Clone, Debug, thiserror::Error)]
#[error("Failed to execute event!\n{err:?}")]
pub struct FireEventError {
err: BaseFireEventError,
@ -10,8 +14,45 @@ impl From<BaseFireEventError> for FireEventError {
}
}
#[derive(Debug, thiserror::Error)]
#[derive(Clone, Debug, thiserror::Error)]
pub enum BaseFireEventError {
#[error("No handler matches the event!")]
NoHandler,
}
#[derive(Debug, Clone, thiserror::Error)]
#[error("Error while executing bus event:\n{root:#?}")]
pub struct CallTrace {
pub root: CallEvent,
}
#[derive(Debug, Clone)]
pub enum Resolution {
Success,
BusError(FireEventError),
}
#[derive(Debug, Clone)]
pub struct CallEvent {
pub handler_name: &'static str,
pub handler_args_t: &'static str,
pub handler_args: String,
pub inner: Vec<Self>,
pub resolution: Option<Resolution>,
pub return_t: &'static str,
pub return_v: Option<String>,
}
impl CallEvent {
pub fn from_event_def<Tag: unique_type::Unique, At: DynDebug + 'static, Rt: DynDebug + 'static>(def: &'static EventDef<Tag, At, Rt>, args: &At) -> Self {
Self {
handler_name: def.name,
handler_args_t: type_name::<At>(),
handler_args: format!("{:#?}", args.as_dbg()),
inner: vec![],
resolution: None,
return_t: type_name::<Rt>(),
return_v: None,
}
}
}

View File

@ -1,7 +1,7 @@
pub mod error;
use core::any::TypeId;
use std::fmt::Debug;
use std::{fmt::Debug, sync::Arc};
use flume::{r#async::RecvFut, Receiver, Sender};
use futures::future::BoxFuture;
@ -15,19 +15,23 @@ use crate::{
async_util::{OneOf, OneOfResult},
dyn_debug::DynDebug,
},
BusStop, EventRegister,
BusStop, EventRegister, bus::error::{CallTrace, CallEvent},
};
use error::{BaseFireEventError, FireEventError};
use self::error::Resolution;
enum Frame {
ReadyToPoll {
interface_recv: Receiver<BusInterfaceEvent>,
recev_fut: RecvFut<'static, BusInterfaceEvent>,
handler_fut: BoxFuture<'static, (BusStopContainer, DynVar)>,
handler: Arc<BusStopContainer>,
handler_fut: BoxFuture<'static, DynVar>,
},
AwaitingNestedCall {
interface_recv: Receiver<BusInterfaceEvent>,
handler_fut: BoxFuture<'static, (BusStopContainer, DynVar)>,
handler: Arc<BusStopContainer>,
handler_fut: BoxFuture<'static, DynVar>,
responder: Sender<Result<DynVar, FireEventError>>,
},
}
@ -63,9 +67,9 @@ impl DABus {
pub fn deregister<T: BusStop + Debug + Send + Sync + 'static>(&mut self) -> Option<T> {
let stop = self
.registered_stops
.drain_filter(|stop| (*stop.inner).as_any().type_id() == TypeId::of::<T>())
.drain_filter(|stop| (*stop.inner.try_lock().unwrap()).as_any().type_id() == TypeId::of::<T>())
.nth(0)
.map(|item| *item.inner.to_any().downcast().unwrap());
.map(|item| *item.inner.into_inner().to_any().downcast().unwrap());
info!("Deregistering stop {:?}", stop);
stop
}
@ -100,27 +104,36 @@ impl DABus {
let interface = BusInterface::new(interface_send);
let recev_fut = interface_recv.clone().into_recv_async();
let handler_fut = unsafe { handler.handle_raw_event(def, args, interface) };
let shared_handler = Arc::new(handler);
let handler_fut = unsafe { shared_handler.clone().handle_raw_event(def, args, interface) };
let frame = Frame::ReadyToPoll {
interface_recv,
recev_fut,
handler: shared_handler,
handler_fut: Box::pin(async move { handler_fut.await }),
};
Ok(frame)
}
async fn raw_fire(&mut self, def: TypeId, args: DynVar) -> Result<DynVar, FireEventError> {
async fn raw_fire(&mut self, def: TypeId, args: DynVar, mut trace: CallTrace) -> (Option<DynVar>, CallTrace) {
let mut stack: Vec<Frame> = vec![];
stack.push(self.gen_frame_for(def, args)?);
stack.push(match self.gen_frame_for(def, args) {
Ok(initial_frame) => initial_frame,
Err(initial_frame_error) => {
trace.root.resolution = Some(Resolution::BusError(initial_frame_error));
return (None, trace)
}
});
'main: loop {
match stack.pop().unwrap() {
Frame::ReadyToPoll {
interface_recv,
recev_fut,
handler,
handler_fut,
} => {
let recv_and_handler_fut = OneOf::new(recev_fut, handler_fut);
@ -131,43 +144,54 @@ impl DABus {
def,
args,
responder,
trace_data,
} => match self.gen_frame_for(def, args) {
Ok(next_frame) => {
trace.root.inner.push(trace_data);
stack.push(Frame::AwaitingNestedCall {
interface_recv,
handler,
handler_fut,
responder,
});
stack.push(next_frame);
}
Err(e) => {
responder.send(Err(e)).unwrap();
let recev_fut = interface_recv.clone().into_recv_async();
stack.push(Frame::ReadyToPoll {
interface_recv,
recev_fut,
handler,
handler_fut,
});
}
},
}
BusInterfaceEvent::FwdError { error } => {
todo!()
}
}
}
OneOfResult::F1(_, (handler, handler_return)) => {
OneOfResult::F1(_, handler_return) => {
self.registered_stops.push(Arc::try_unwrap(handler).unwrap());
if stack.is_empty() {
self.registered_stops.push(handler);
break 'main Ok(handler_return);
trace.root.resolution = Some(Resolution::Success);
trace.root.return_v = Some(format!("{:#?}", handler_return.as_dbg()));
break 'main (Some(handler_return), trace);
} else {
if let Frame::AwaitingNestedCall {
interface_recv,
handler: returned_handler,
handler_fut,
responder,
} = stack.pop().unwrap()
{
self.registered_stops.push(handler);
responder.send(Ok(handler_return)).unwrap();
let recev_fut = interface_recv.clone().into_recv_async();
stack.push(Frame::ReadyToPoll {
interface_recv,
handler: returned_handler,
recev_fut,
handler_fut,
});
@ -193,12 +217,22 @@ impl DABus {
&mut self,
def: &'static EventDef<Tag, At, Rt>,
args: At,
) -> Result<Rt, FireEventError> {
) -> Result<Rt, CallTrace> {
info!("Firing initial event: {:?}", def.name);
let trace = CallTrace {
root: CallEvent::from_event_def(def, &args),
};
let _ = def;
let def = TypeId::of::<Tag>();
let args = DynVar::new(args);
Ok(unsafe { self.raw_fire(def, args).await?.try_to_unchecked::<Rt>() })
match self.raw_fire(def, args, trace).await {
(Some(return_v), _trace) => {
Ok(return_v.try_to().unwrap())
}
(None, trace) => {
Err(trace)
}
}
}
}

View File

@ -1,9 +1,10 @@
use std::any::TypeId;
use flume::Sender;
use futures::pending;
use crate::{
bus::error::FireEventError, core::dyn_var::DynVar, util::dyn_debug::DynDebug, EventDef,
bus::error::{FireEventError, CallEvent}, core::dyn_var::DynVar, util::dyn_debug::DynDebug, EventDef,
};
pub(crate) enum BusInterfaceEvent {
@ -11,6 +12,10 @@ pub(crate) enum BusInterfaceEvent {
def: TypeId,
args: DynVar,
responder: Sender<Result<DynVar, FireEventError>>,
trace_data: CallEvent,
},
FwdError {
error: FireEventError,
},
}
@ -38,6 +43,7 @@ impl BusInterface {
def: &'static EventDef<Tag, At, Rt>,
args: At,
) -> Result<Rt, FireEventError> {
let trace_data = CallEvent::from_event_def(def, &args);
let _ = def;
let def = TypeId::of::<Tag>();
let args = DynVar::new(args);
@ -47,6 +53,7 @@ impl BusInterface {
def,
args,
responder,
trace_data,
})
.unwrap();
Ok(response
@ -57,41 +64,40 @@ impl BusInterface {
.unwrap())
}
// unimplemented as this needs to be re-designed
// /// takes a error (from a nested call, presumablely) and forwards it to the caller of the current event (via the runtime and a deal with the devil)
// ///
// /// this is a easy way to handle errors, as it will forward the error, and can produce nice backtraces (soonTM)
// ///
// /// this returns ! because as soon as this is polled by the runtime (i think) the future of the bus event will be dropped.
// /// (hopefully that wont do anything bad?)
// pub async fn fwd_bus_err(
// self, /* not needed, but just to enforce the this-is-the-last-thing-you-do theme */
// error: FireEventError,
// ) -> ! {
// self.channel
// .send(BusInterfaceEvent::FwdError { error })
// .unwrap();
// pending!();
// unsafe {
// // anyone who gets this far deserves it
// std::hint::unreachable_unchecked()
// }
// }
/// takes a error (from a nested call, presumablely) and forwards it to the caller of the current event (via the runtime and a deal with the devil)
///
/// this is a easy way to handle errors, as it will forward the error, and can produce nice backtraces (soonTM)
///
/// this returns ! because as soon as this is polled by the runtime (i think) the future of the bus event will be dropped.
/// (hopefully that wont do anything bad?)
pub async fn fwd_bus_err(
self, /* not needed, but just to enforce the this-is-the-last-thing-you-do theme */
error: FireEventError,
) -> ! {
self.channel
.send(BusInterfaceEvent::FwdError { error })
.unwrap();
pending!();
unsafe {
// anyone who gets this far deserves it
std::hint::unreachable_unchecked()
}
}
}
// /// Utility for handling bus errors inside of bus handlers
// #[async_trait]
// pub trait BusErrorUtil<T> {
// /// unwraps an `Result`, or forwards the error to [`BusInterface::fwd_bus_err`]
// async fn unwrap_or_fwd(self, bus: BusInterface) -> T;
// }
/// Utility for handling bus errors inside of bus handlers
#[async_trait]
pub trait BusErrorUtil<T> {
/// unwraps an `Result`, or forwards the error to [`BusInterface::fwd_bus_err`]
async fn unwrap_or_fwd(self, bus: BusInterface) -> T;
}
// #[async_trait]
// impl<T: Send> BusErrorUtil<T> for Result<T, FireEventError> {
// async fn unwrap_or_fwd(self, bus: BusInterface) -> T {
// match self {
// Ok(x) => x,
// Err(err) => bus.fwd_bus_err(err).await,
// }
// }
// }
#[async_trait]
impl<T: Send> BusErrorUtil<T> for Result<T, FireEventError> {
async fn unwrap_or_fwd(self, bus: BusInterface) -> T {
match self {
Ok(x) => x,
Err(err) => bus.fwd_bus_err(err).await,
}
}
}

View File

@ -1,4 +1,6 @@
use std::{any::TypeId, fmt::Debug};
use std::{any::TypeId, fmt::Debug, sync::Arc};
use futures::lock::Mutex;
use crate::{
core::dyn_var::DynVar, event::EventRegister, interface::BusInterface, util::{GeneralRequirements, dyn_debug::DynDebug},
@ -141,40 +143,43 @@ pub(crate) trait BusStopReq: DynBusStopContainer + GeneralRequirements {}
impl<T: DynBusStopContainer + GeneralRequirements> BusStopReq for T {}
pub(crate) struct BusStopContainer {
pub(crate) inner: Box<dyn BusStopReq + Send + Sync + 'static>,
pub(crate) inner: Mutex<Box<dyn BusStopReq + Send + Sync + 'static>>,
}
impl BusStopContainer {
pub const fn new(inner: Box<dyn BusStopReq + Send + Sync + 'static>) -> Self {
Self { inner }
pub fn new(inner: Box<dyn BusStopReq + Send + Sync + 'static>) -> Self {
Self { inner: Mutex::new(inner) }
}
pub async unsafe fn handle_raw_event(
mut self,
self: Arc<Self>,
event_tag_id: TypeId,
event: DynVar, /* must be the hidden event type */
interface: BusInterface,
) -> (Self, DynVar) {
) -> DynVar {
let ret = self
.inner
.try_lock()
.unwrap()
.handle_raw_event(event_tag_id, event, interface)
.await;
(self, ret)
ret
}
pub fn relevant(&mut self, event_tag_id: TypeId) -> bool {
self.inner.relevant(event_tag_id)
self.inner.try_lock().unwrap().relevant(event_tag_id)
}
pub fn debug(&self) -> &dyn Debug {
self.inner.debug()
pub fn debug(&mut self) -> &dyn Debug {
let i = self.inner.get_mut();
(**i).as_dbg()
}
}
impl Debug for BusStopContainer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("BusStopContainer")
.field("inner", self.debug())
.field("inner", self.inner.try_lock().unwrap().as_dbg())
.finish()
}
}