vtui_core/
transport.rs

1use std::{
2    sync::mpsc::{Receiver, Sender},
3    time::Duration,
4};
5
6use crate::{error::SendError, events::Message};
7
8pub struct EventSource {
9    tx: Sender<Message>,
10    rx: Receiver<Message>,
11}
12
13impl Default for EventSource {
14    fn default() -> Self {
15        let (tx, rx) = std::sync::mpsc::channel();
16        Self { tx, rx }
17    }
18}
19
20impl EventSource {
21    pub fn new() -> Self {
22        Self::default()
23    }
24
25    pub fn subscribe(&self, producer: &impl EventProducer) {
26        let sink = EventSink(self.tx.clone());
27        producer.spawn(sink);
28    }
29
30    pub(crate) fn recv(&self) -> Message {
31        self.rx.recv().unwrap()
32    }
33
34    pub(crate) fn recv_timeout(&self, budget: Duration) -> Option<Message> {
35        self.rx.recv_timeout(budget).ok()
36    }
37}
38
39#[derive(Clone, Debug)]
40pub struct EventSink(Sender<Message>);
41
42impl EventSink {
43    pub fn send(&self, value: Message) -> Result<(), SendError> {
44        self.0.send(value).map_err(|_| SendError)
45    }
46}
47
48pub trait EventProducer {
49    fn subscribe(tx: EventSink);
50
51    fn spawn(&self, tx: EventSink) {
52        std::thread::spawn(move || {
53            Self::subscribe(tx);
54        });
55    }
56}