use std::error::Error;
use std::fmt::{Display, Formatter};
use std::io::{Stderr, Write};
use std::sync::{Arc, Mutex};
use std::time::Duration;
use std::{io, thread};
use storyteller::{
event_channel, ChannelEventListener, ChannelReporter, EventHandler, EventListener,
EventReporter, FinishProcessing,
};
fn main() {
let (sender, receiver) = event_channel::<ExampleEvent>();
let handler = JsonHandler::default();
let reporter = ChannelReporter::new(sender);
let listener = ChannelEventListener::new(receiver);
let event_handler = Arc::new(handler);
let finalize_handler = listener.run_handler(event_handler);
my_programming_logic(&reporter).unwrap();
reporter.disconnect().unwrap();
finalize_handler.finish_processing().unwrap();
}
fn my_programming_logic(reporter: &ChannelReporter<ExampleEvent>) -> Result<(), Box<dyn Error>> {
reporter.report_event(ExampleEvent::text("One"))?;
reporter.report_event(ExampleEvent::event(MyEvent::Increment))?;
reporter.report_event(ExampleEvent::event(MyEvent::Increment))?;
reporter.report_event(ExampleEvent::text("Two before reset"))?;
reporter.report_event(ExampleEvent::event(MyEvent::Reset))?;
reporter.report_event(ExampleEvent::text("Two after reset"))?;
reporter.report_event(ExampleEvent::event(MyEvent::Increment))?;
reporter.report_event(ExampleEvent::event(MyEvent::Increment))?;
reporter.report_event(ExampleEvent::event(MyEvent::Increment))?;
reporter.report_event(ExampleEvent::event(MyEvent::Increment))?;
reporter.report_event(ExampleEvent::event(MyEvent::Increment))?;
reporter.report_event(ExampleEvent::event(MyEvent::Increment))?;
reporter.report_event(ExampleEvent::text("Three"))?;
reporter.report_event(ExampleEvent::event(MyEvent::Increment))?;
reporter.report_event(ExampleEvent::event(MyEvent::Increment))?;
reporter.report_event(ExampleEvent::event(MyEvent::Increment))?;
reporter.report_event(ExampleEvent::text("Four"))?;
Ok(())
}
#[derive(Debug)]
enum ExampleEvent {
Event(MyEvent),
Text(String),
}
impl Display for ExampleEvent {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("{:?}", self))
}
}
impl ExampleEvent {
pub fn event(event: MyEvent) -> Self {
Self::Event(event)
}
pub fn text<T: AsRef<str>>(text: T) -> Self {
Self::Text(text.as_ref().to_string())
}
}
impl ExampleEvent {
pub fn to_json(&self) -> String {
match self {
Self::Event(event) => event.to_json(),
Self::Text(msg) => format!("{{ \"event\" : \"message\", \"value\" : \"{}\" }}", msg),
}
}
}
#[derive(Debug)]
enum MyEvent {
Increment,
Reset,
}
impl MyEvent {
pub fn to_json(&self) -> String {
match self {
Self::Increment => format!("{{ \"event\" : \"increment\" }}"),
Self::Reset => format!("{{ \"event\" : \"reset\" }}"),
}
}
}
impl Display for MyEvent {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("{:?}", self))
}
}
struct JsonHandler {
stream: Arc<Mutex<Stderr>>,
}
impl Default for JsonHandler {
fn default() -> Self {
Self {
stream: Arc::new(Mutex::new(io::stderr())),
}
}
}
impl EventHandler for JsonHandler {
type Event = ExampleEvent;
fn handle(&self, event: Self::Event) {
thread::sleep(Duration::from_secs(1));
let message = event.to_json();
let mut out = self.stream.lock().unwrap();
let _ = writeln!(out, "{}", message);
let _ = out.flush();
}
fn finish(&self) {
let mut out = self.stream.lock().unwrap();
let message = format!("{{ \"event\" : \"program-finished\", \"success\" : true }}");
let _ = writeln!(out, "{}", message);
let _ = out.flush();
}
}