pub use i3ipc_types::*;
use serde::de::DeserializeOwned;
use std::{
io::{self, Read, Write},
os::unix::net::UnixStream,
};
pub struct I3;
#[derive(Debug)]
pub struct I3Stream(UnixStream);
impl I3IPC for I3Stream {}
impl I3Protocol for I3Stream {}
impl Connect for I3 {
type Stream = I3Stream;
fn connect() -> io::Result<I3Stream> {
Ok(I3Stream(UnixStream::connect(socket_path()?)?))
}
}
impl I3Stream {
pub fn conn_sub<E>(events: E) -> io::Result<Self>
where
E: AsRef<[event::Subscribe]>,
{
let mut i3 = I3::connect()?;
i3.subscribe(events)?;
Ok(i3)
}
pub 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(msg::Msg::Subscribe, sub_json)?;
let resp: MsgResponse<reply::Success> = self.receive_msg()?;
Ok(resp.body)
}
pub fn listen(&'_ mut self) -> I3Iter<'_> {
I3Iter { stream: self }
}
pub fn iter(&'_ mut self) -> I3Iter<'_> {
I3Iter { stream: self }
}
pub fn send_msg<P>(&mut self, msg: msg::Msg, payload: P) -> io::Result<usize>
where
P: AsRef<str>,
{
let buf = self.encode_msg_body(msg, payload);
self.write(&buf[..])
}
pub fn receive_msg<D: DeserializeOwned>(&mut self) -> io::Result<MsgResponse<D>> {
let (msg_type, payload_bytes) = self.decode_msg()?;
MsgResponse::new(msg_type, payload_bytes)
}
pub fn receive_event(&mut self) -> io::Result<event::Event> {
let (evt_type, payload_bytes) = self.decode_msg()?;
decode_event(evt_type, payload_bytes)
}
pub fn send_receive<P, D>(&mut self, msg: msg::Msg, payload: P) -> io::Result<MsgResponse<D>>
where
P: AsRef<str>,
D: DeserializeOwned,
{
self.send_msg(msg, payload)?;
self.receive_msg()
}
pub fn run_command<S: AsRef<str>>(&mut self, payload: S) -> io::Result<Vec<reply::Success>> {
self.send_msg(msg::Msg::RunCommand, payload)?;
Ok(self.receive_msg()?.body)
}
pub fn get_workspaces(&mut self) -> io::Result<reply::Workspaces> {
let buf = self.encode_msg(msg::Msg::Workspaces);
self.write_all(&buf[..])?;
let resp: MsgResponse<Vec<reply::Workspace>> = self.receive_msg()?;
Ok(resp.body)
}
pub fn get_outputs(&mut self) -> io::Result<reply::Outputs> {
let buf = self.encode_msg(msg::Msg::Outputs);
self.write_all(&buf[..])?;
Ok(self.receive_msg()?.body)
}
pub fn get_tree(&mut self) -> io::Result<reply::Node> {
let buf = self.encode_msg(msg::Msg::Tree);
self.write_all(&buf[..])?;
Ok(self.receive_msg()?.body)
}
pub fn get_marks(&mut self) -> io::Result<reply::Marks> {
let buf = self.encode_msg(msg::Msg::Marks);
self.write_all(&buf[..])?;
Ok(self.receive_msg()?.body)
}
pub fn get_bar_ids(&mut self) -> io::Result<reply::BarIds> {
let buf = self.encode_msg(msg::Msg::BarConfig);
self.write_all(&buf[..])?;
Ok(self.receive_msg()?.body)
}
pub fn get_bar_config<S: AsRef<str>>(&mut self, bar_id: S) -> io::Result<reply::BarConfig> {
self.send_msg(msg::Msg::BarConfig, bar_id)?;
Ok(self.receive_msg()?.body)
}
pub fn get_version(&mut self) -> io::Result<reply::Version> {
let buf = self.encode_msg(msg::Msg::Version);
self.write_all(&buf[..])?;
Ok(self.receive_msg()?.body)
}
pub fn get_binding_modes(&mut self) -> io::Result<reply::BindingModes> {
let buf = self.encode_msg(msg::Msg::BindingModes);
self.write_all(&buf[..])?;
Ok(self.receive_msg()?.body)
}
pub fn get_config(&mut self) -> io::Result<reply::Config> {
let buf = self.encode_msg(msg::Msg::Config);
self.write_all(&buf[..])?;
Ok(self.receive_msg()?.body)
}
pub fn get_tick(&mut self) -> io::Result<reply::Success> {
let buf = self.encode_msg(msg::Msg::Tick);
self.write_all(&buf[..])?;
Ok(self.receive_msg()?.body)
}
pub fn get_sync(&mut self) -> io::Result<reply::Success> {
let buf = self.encode_msg(msg::Msg::Sync);
self.write_all(&buf[..])?;
Ok(self.receive_msg()?.body)
}
pub fn get_binding_state(&mut self) -> io::Result<reply::BindingState> {
let buf = self.encode_msg(msg::Msg::BindingState);
self.write_all(&buf[..])?;
Ok(self.receive_msg()?.body)
}
}
impl Read for I3Stream {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.0.read(buf)
}
}
impl Write for I3Stream {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.0.flush()
}
}
#[derive(Debug)]
pub struct I3Iter<'a> {
stream: &'a mut I3Stream,
}
impl<'a> Iterator for I3Iter<'a> {
type Item = io::Result<event::Event>;
fn next(&mut self) -> Option<Self::Item> {
Some(self.stream.receive_event())
}
}