use std::fmt::{Debug, Display};
use serde::Serialize;
pub use self::channel::{SendError, event_channel};
pub use self::receiver::EventReceiver;
pub use self::sender::EventSender;
mod channel;
mod receiver;
mod sender;
pub trait Artifact: Display + Debug + Send + Sync + erased_serde::Serialize {}
impl<T> Artifact for T where T: Display + Serialize + Debug + Send + Sync + 'static {}
erased_serde::serialize_trait_object!(Artifact);
#[derive(Debug)]
pub enum Event {
Message(String),
Detail(String),
Artifact(Box<dyn Artifact>),
}
#[cfg(test)]
mod tests {
#![allow(clippy::missing_panics_doc)]
use std::fmt;
use serde::Serialize;
use super::*;
#[derive(Clone, Debug, Serialize)]
struct TestArtifact {
value: String,
}
impl fmt::Display for TestArtifact {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.value)
}
}
fn test_artifact() -> TestArtifact {
TestArtifact {
value: "hello".to_string(),
}
}
#[test]
fn artifact_debug_delegates_to_inner_type() {
let event = Event::Artifact(Box::new(test_artifact()));
let debug = format!("{event:?}");
assert!(debug.contains("hello"));
}
#[test]
fn artifact_display_renders_via_display_trait() {
let boxed: Box<dyn Artifact> = Box::new(test_artifact());
let display = boxed.to_string();
assert_eq!(display, "hello");
}
#[test]
fn artifact_serializes_via_erased_serde() {
let boxed: Box<dyn Artifact> = Box::new(test_artifact());
let json = serde_json::to_string(&boxed).expect("should serialize");
assert_eq!(json, r#"{"value":"hello"}"#);
}
#[test]
fn detail_with_empty_string_is_valid() {
let event = Event::Detail(String::new());
let debug = format!("{event:?}");
assert!(debug.contains("Detail"));
}
#[test]
fn message_with_empty_string_is_valid() {
let event = Event::Message(String::new());
let debug = format!("{event:?}");
assert!(debug.contains("Message"));
}
#[test]
fn trait_send() {
fn assert_send<T: Send>() {}
assert_send::<Event>();
}
#[test]
fn trait_sync() {
fn assert_sync<T: Sync>() {}
assert_sync::<Event>();
}
#[test]
fn trait_unpin() {
fn assert_unpin<T: Unpin>() {}
assert_unpin::<Event>();
}
}