rustybar/src/output.rs

59 lines
1.6 KiB
Rust

use crate::tile::{Block, TileData};
use eyre::OptionExt;
use std::sync::Arc;
use tokio::{
io::{self, AsyncWriteExt},
sync::mpsc,
};
use uuid::Uuid;
pub struct OutputChannel {
sender: mpsc::Sender<TileData>,
sender_id: usize,
instance: Arc<str>,
}
impl OutputChannel {
pub fn with_random_uuid(sender: mpsc::Sender<TileData>, sender_id: usize) -> Self {
Self {
sender,
sender_id,
instance: Uuid::new_v4().to_string().into(),
}
}
pub async fn send(&self, mut block: Block) -> Result<(), mpsc::error::SendError<TileData>> {
block.instance = self.instance.clone();
self.sender
.send(TileData {
block,
sender_id: self.sender_id,
})
.await
}
}
pub async fn run(num_tiles: usize, mut receiver: mpsc::Receiver<TileData>) -> eyre::Result<()> {
let mut stdout = io::stdout();
stdout.write_all(b"{ \"version\": 1 }\n[").await?;
let mut blocks = Vec::new();
blocks.resize_with(num_tiles, Default::default);
loop {
let message = receiver
.recv()
.await
.ok_or_eyre("No more messages to recieve")?;
if message.sender_id < num_tiles {
blocks[message.sender_id] = Some(message.block);
} else {
eprintln!("Invalid message with sender id {}", message.sender_id);
continue;
}
let mut serialized = serde_json::to_vec(&blocks).unwrap();
serialized.extend_from_slice(b",\n");
stdout.write_all(&serialized).await?;
}
}