diff options
| author | MaxVerevkin <maxxverrr@gmail.com> | 2023-01-02 20:23:35 +0200 |
|---|---|---|
| committer | Max Verevkin <34583604+MaxVerevkin@users.noreply.github.com> | 2023-01-02 20:44:14 +0200 |
| commit | eebeed1f2774146c3d7df90c7a982f58428d4cff (patch) | |
| tree | c038e06100fbd8b4debf29c5b077d51a56a5f98b /src/status_cmd.rs | |
| parent | 2570f39b5daf6e2a13b3973d47aa7c67fbb457fb (diff) | |
| download | i3bar-mango-eebeed1f2774146c3d7df90c7a982f58428d4cff.tar.gz | |
rewrite using wayrs
Diffstat (limited to 'src/status_cmd.rs')
| -rw-r--r-- | src/status_cmd.rs | 86 |
1 files changed, 29 insertions, 57 deletions
diff --git a/src/status_cmd.rs b/src/status_cmd.rs index 4d9c453..f6c9c2c 100644 --- a/src/status_cmd.rs +++ b/src/status_cmd.rs @@ -1,22 +1,22 @@ -use std::io::{BufRead, BufReader, Write}; -use std::os::unix::prelude::AsRawFd; -use std::process::{Child, ChildStdin, ChildStdout, Command, Stdio}; +use std::io::Write; +use std::process::{Child, ChildStdin, Command, Stdio}; use anyhow::Result; -use tokio::io::unix::AsyncFd; -use tokio::io::Interest; +use tokio::io::AsyncReadExt; +use tokio::process::ChildStdout; use crate::i3bar_protocol::{Block, Event, Protocol}; +const INITIAL_BUF_CAPACITY: usize = 4096; + #[derive(Debug)] pub struct StatusCmd { pub child: Child, - output: BufReader<ChildStdout>, + pub output: ChildStdout, input: ChildStdin, protocol: Protocol, buf: Vec<u8>, - pub async_fd: AsyncFd<i32>, } impl StatusCmd { @@ -28,73 +28,45 @@ impl StatusCmd { .spawn()?; let output = child.stdout.take().unwrap(); let input = child.stdin.take().unwrap(); - let async_fd = AsyncFd::with_interest(output.as_raw_fd(), Interest::READABLE)?; Ok(Self { child, - output: BufReader::new(output), + output: ChildStdout::from_std(output)?, input, protocol: Protocol::Unknown, - buf: Vec::new(), - async_fd, + buf: Vec::with_capacity(INITIAL_BUF_CAPACITY), }) } pub fn notify_available(&mut self) -> Result<Option<Vec<Block>>> { - let buf = self.output.fill_buf()?; - if buf.is_empty() { - bail!("status command exited"); - } - if self.buf.is_empty() { - let rem = self.protocol.process_new_bytes(buf)?; - if !rem.is_empty() { - self.buf.extend_from_slice(rem); - } + let rem = self.protocol.process_new_bytes(&self.buf)?; + if rem.is_empty() { + self.buf.clear(); } else { - self.buf.extend_from_slice(buf); - let rem = self.protocol.process_new_bytes(&self.buf)?; - if rem.is_empty() { - self.buf.clear(); - } else { - let used = self.buf.len() - rem.len(); - self.buf.drain(..used); - } + let used = self.buf.len() - rem.len(); + self.buf.drain(..used); } - let consumed = buf.len(); - self.output.consume(consumed); Ok(self.protocol.get_blocks()) } + pub async fn read(&mut self) -> Result<()> { + assert!(self.buf.capacity() >= INITIAL_BUF_CAPACITY); + if self.buf.capacity() == self.buf.len() { + // Double the capacity + self.buf.reserve(self.buf.len()); + } + + let read_len = self.output.read_buf(&mut self.buf).await?; + if read_len == 0 { + bail!("status command exited"); + } + + Ok(()) + } + pub fn send_click_event(&mut self, event: &Event) -> Result<()> { if self.protocol.supports_clicks() { writeln!(self.input, "{}", serde_json::to_string(event).unwrap())?; } Ok(()) } - - // pub fn quick_insert(&self, handle: LoopHandle<BarState>) { - // handle - // .insert_source( - // calloop::generic::Generic::new( - // self.output.get_ref().as_raw_fd(), - // calloop::Interest { - // readable: true, - // writable: false, - // }, - // calloop::Mode::Level, - // ), - // move |ready, _, bar_state| { - // if ready.readable { - // bar_state.notify_available()?; - // Ok(calloop::PostAction::Continue) - // } else { - // bar_state.set_error("error reading from status command"); - // if let Some(mut child) = bar_state.status_cmd.take() { - // let _ = child.child.kill(); - // } - // Ok(calloop::PostAction::Remove) - // } - // }, - // ) - // .expect("failed to inser calloop source"); - // } } |
