#![doc(html_root_url = "https://docs.rs/async-i3ipc/0.7.0")]
pub use i3ipc_types::*;
pub mod stream;
mod util;
pub use stream::EventStream;
pub use util::*;
use async_std::{os::unix::net::UnixStream, prelude::*};
use serde::de::DeserializeOwned;
use std::io;
#[derive(Debug)]
pub struct I3 {
stream: UnixStream,
}
impl I3 {
async fn _send_msg<P>(&mut self, msg: msg::Msg, payload: Option<P>) -> io::Result<()>
where
P: AsRef<str>,
{
let buf = self.stream._encode_msg(msg, payload);
self.stream.write_all(&buf).await
}
async fn _decode_msg(&mut self) -> io::Result<(u32, Vec<u8>)> {
let mut init = [0_u8; 14];
self.stream.read_exact(&mut init).await?;
assert!(&init[0..6] == MAGIC.as_bytes(), "Magic str not received");
let payload_len = u32::from_ne_bytes([init[6], init[7], init[8], init[9]]) as usize;
let msg_type = u32::from_ne_bytes([init[10], init[11], init[12], init[13]]);
let mut payload = vec![0_u8; payload_len];
self.stream.read_exact(&mut payload).await?;
Ok((msg_type, payload))
}
pub async fn connect() -> io::Result<Self> {
Ok(I3 {
stream: UnixStream::connect(socket_path()?).await?,
})
}
pub async fn send_msg_body<P>(&mut self, msg: msg::Msg, payload: P) -> io::Result<()>
where
P: AsRef<str>,
{
self._send_msg(msg, Some(payload)).await
}
pub async fn send_msg(&mut self, msg: msg::Msg) -> io::Result<()> {
self._send_msg::<&str>(msg, None).await
}
pub async fn read_msg<D>(&mut self) -> io::Result<MsgResponse<D>>
where
D: DeserializeOwned,
{
let (msg_type, payload) = self._decode_msg().await?;
Ok(MsgResponse {
msg_type: msg_type.into(),
body: serde_json::from_slice(&payload[..])?,
})
}
pub async fn read_event(&mut self) -> io::Result<event::Event> {
let (evt_type, payload_bytes) = self._decode_msg().await?;
decode_event(evt_type, payload_bytes)
}
pub async fn send_read<P, D>(&mut self, msg: msg::Msg, payload: P) -> io::Result<MsgResponse<D>>
where
P: AsRef<str>,
D: DeserializeOwned,
{
self.send_msg_body(msg, payload).await?;
self.read_msg().await
}
pub async fn subscribe<E>(&mut self, events: E) -> io::Result<reply::Success>
where
E: AsRef<[event::Subscribe]>,
{
let sub_json = serde_json::to_string(events.as_ref())?;
self.send_msg_body(msg::Msg::Subscribe, sub_json).await?;
Ok(self.read_msg::<reply::Success>().await?.body)
}
pub fn listen(self) -> EventStream {
EventStream::new(self.stream)
}
pub async fn run_command<S: AsRef<str>>(
&mut self,
payload: S,
) -> io::Result<Vec<reply::Success>> {
self.send_msg_body(msg::Msg::RunCommand, payload).await?;
Ok(self.read_msg().await?.body)
}
pub async fn get_workspaces(&mut self) -> io::Result<reply::Workspaces> {
self.send_msg(msg::Msg::Workspaces).await?;
let resp: MsgResponse<Vec<reply::Workspace>> = self.read_msg().await?;
Ok(resp.body)
}
pub async fn get_outputs(&mut self) -> io::Result<reply::Outputs> {
self.send_msg(msg::Msg::Outputs).await?;
Ok(self.read_msg().await?.body)
}
pub async fn get_tree(&mut self) -> io::Result<reply::Node> {
self.send_msg(msg::Msg::Tree).await?;
Ok(self.read_msg().await?.body)
}
pub async fn get_marks(&mut self) -> io::Result<reply::Marks> {
self.send_msg(msg::Msg::Marks).await?;
Ok(self.read_msg().await?.body)
}
pub async fn get_bar_ids(&mut self) -> io::Result<reply::BarIds> {
self.send_msg(msg::Msg::BarConfig).await?;
Ok(self.read_msg().await?.body)
}
pub async fn get_bar_config<S: AsRef<str>>(
&mut self,
bar_id: S,
) -> io::Result<reply::BarConfig> {
self.send_msg_body(msg::Msg::BarConfig, bar_id).await?;
Ok(self.read_msg().await?.body)
}
pub async fn get_version(&mut self) -> io::Result<reply::Version> {
self.send_msg(msg::Msg::Version).await?;
Ok(self.read_msg().await?.body)
}
pub async fn get_binding_modes(&mut self) -> io::Result<reply::BindingModes> {
self.send_msg(msg::Msg::BindingModes).await?;
Ok(self.read_msg().await?.body)
}
pub async fn get_config(&mut self) -> io::Result<reply::Config> {
self.send_msg(msg::Msg::Config).await?;
Ok(self.read_msg().await?.body)
}
pub async fn get_tick(&mut self) -> io::Result<reply::Success> {
self.send_msg(msg::Msg::Tick).await?;
Ok(self.read_msg().await?.body)
}
pub async fn get_sync(&mut self) -> io::Result<reply::Success> {
self.send_msg(msg::Msg::Sync).await?;
Ok(self.read_msg().await?.body)
}
pub async fn get_binding_state(&mut self) -> io::Result<reply::BindingState> {
self.send_msg(msg::Msg::BindingState).await?;
Ok(self.read_msg().await?.body)
}
}