···3344/// A newtype over [Quote] used to prompt the [SinkManager] to
55/// submit a new quote to all its configured sinks.
66+#[derive(Debug, Clone)]
67pub struct PostQuote(pub Quote);
7889/// Error type for internal communication between
···5657/// The SinkManager will attempt to reinitialize failed sinks upon
5758/// encountering recoverable errors.
5859#[derive(Actor)]
5959-pub struct SinkManager<S: QuoteSink> {
6060+pub struct SinkManager {
6061 // Uh oh. As the [Actor] trait is *not* dyn-compatible,
6162 // and I do not own its definition, I'm fairly certain that I cannot
6263 // do asynchronous dynamic dispatch for it here.
6363- // We will have to use multiple vectors with static dispatch, instead...
6464- sinks: Vec<ActorRef<S>>,
6464+ // I've decided I'll limit this to one sink per implementation right now.
6565+ stdout_sink: Option<ActorRef<StdoutSink>>,
6666+ // ...
6767+}
6868+6969+impl SinkManager {
7070+ pub fn new(stdout_sink: Option<ActorRef<StdoutSink>>) -> Self {
7171+ Self { stdout_sink }
7272+ }
7373+}
7474+7575+pub type SinkReplies = Vec<Result<(), ()>>;
7676+7777+impl Message<PostQuote> for SinkManager {
7878+ type Reply = SinkReplies;
7979+8080+ async fn handle(
8181+ &mut self,
8282+ msg: PostQuote,
8383+ _ctx: &mut Context<Self, Self::Reply>,
8484+ ) -> Self::Reply {
8585+ use futures::future::join_all;
8686+8787+ // We'll see if this monstrosity actually works
8888+ let sinks = [self.stdout_sink.clone()];
8989+ let futures = sinks
9090+ .iter()
9191+ .flatten()
9292+ .map(|s| s.ask(msg.clone()).into_future());
9393+ let results = join_all(futures).await;
9494+9595+ results.iter().map(|r| r.clone().or(Err(()))).collect()
9696+ }
9797+}
9898+9999+mod test {
100100+ #[tokio::test]
101101+ async fn stdout_sink() {
102102+ use super::*;
103103+104104+ let stdout = StdoutSink::spawn(StdoutSink);
105105+ let manager = SinkManager::spawn(SinkManager::new(Some(stdout)));
106106+107107+ let messages = ["First test!", "Second test.", "Third..."];
108108+ for msg in messages {
109109+ manager.tell(PostQuote(msg.into())).await.unwrap();
110110+ tokio::time::sleep(std::time::Duration::from_secs(5)).await;
111111+ }
112112+113113+ // Hopefully we don't crash...!
114114+ // TODO: Sink that actually stores every quote it "posts"?
115115+ // Could help in verifying everything was sent correctly.
116116+ }
65117}