This crate provides types and functions for working with i3's IPC protocol within tokio. It re-exports the subcrate i3ipc-types
because it is also used for a synchronous version of the code.
There are many ways you cna interact with this library. You can import an already written future and simply spawn/run it, or you can use the building blocks to construct your own futures.
I expect the most common use case will be to subscribe to some events and listen over a channel:
```rust use futures::{ future, sink::Sink, stream::Stream, sync::mpsc::{self, Sender}, Future, }; use std::io; use tokio_i3ipc::{subscribe, event::{self, Subscribe}};
fn main() -> io::Result<()> {
let mut rt =
tokio::runtime::currentthread::Runtime::new().expect("Failed building runtime");
// create a channel to receive responses
let (tx, rx) = mpsc::channel(5);
// pass a handle and Sender
to subscribe
subscribe(rt.handle(), tx, vec![Subscribe::Window])?;
// handle the events received on the channel
let fut = rx.foreach(|e: event::Event| {
println!("received");
println!("{:#?}", e);
future::ok(())
});
rt.spawn(fut);
rt.run().expect("failed runtime");
Ok(())
}
```
But all the tools are exported to build something like this yourself, interact with i3 in any way you like:
```rust use tokio::codec::FramedRead; use tokio_uds::UnixStream; use futures::{future::Future, stream::Stream, sink::Sink, sync::mpsc::Sender}; use std::io;
use tokioi3ipc::{Connect, subscribefuture, event, I3, codec::EventCodec};
pub fn subscribe(
rt: tokio::runtime::currentthread::Handle,
tx: Sender
rt.spawn(fut);
Ok(())
} ```
Another example, getting all displays from i3:
```rust use std::io; use futures::future::Future; use tokio_i3ipc::{get, I3, Connect};
pub fn getdisplays() -> io::Result<()> { let fut = I3::connect()? .andthen(get::getoutputs) .andthen(|resp| { dbg!(resp); Ok(()) }) .map(|| ()) .maperr(|e| println!("{}", e)); Ok(()) } ```
or, you could write get_outputs
yourself:
```rust use tokiouds::UnixStream; use futures::future::Future; use std::io; use tokioi3ipc::{reply, msg::Msg, MsgResponse, event, io as i3io};
pub fn getoutputs(
stream: UnixStream,
) -> impl Future
send_msg
, write_msg_json
and write_msg
will handle writing to i3. read_msg
and read_msg_and
will handle reading. The latter returns the stream again to continue using it.
To send messages to i3, there are a number of convenience futures that need only be passed a UnixStream
and then run in your event loop.
```rust use futures::future::Future; use tokiouds::UnixStream; use tokio; use tokioi3ipc::{I3, Connect, MsgResponse, get, reply};
fn main() {
let fut = I3::connect()
.expect("unable to get socket")
.andthen(get::getworkspaces)
.andthen(
|(stream, reply): (UnixStream, MsgResponse