swayipc_async/
connection.rs1use super::common::receive_from_stream;
2use super::socket::get_socketpath;
3use crate::{CommandType::*, Error::SubscriptionFailed, *};
4use async_io::{Async, Timer};
5use futures_lite::AsyncWriteExt;
6use serde::de::DeserializeOwned as Deserialize;
7use std::io::ErrorKind::NotConnected;
8use std::os::unix::net::UnixStream;
9use std::time::Duration;
10
11#[derive(Debug)]
12pub struct Connection(Async<UnixStream>);
13
14impl Connection {
15 pub async fn new() -> Fallible<Self> {
17 let socketpath = get_socketpath().await?;
18 loop {
19 let stream = Async::<UnixStream>::connect(socketpath.as_path()).await;
20 if matches!(stream.as_ref().map_err(|e| e.kind()), Err(NotConnected)) {
21 Timer::after(Duration::from_millis(100)).await;
22 } else {
23 return Ok(Self(stream?));
24 }
25 }
26 }
27
28 async fn raw_command<D: Deserialize>(&mut self, command_type: CommandType) -> Fallible<D> {
29 self.0.write_all(command_type.encode().as_slice()).await?;
30 command_type.decode(receive_from_stream(&mut self.0).await?)
31 }
32
33 async fn raw_command_with<D: Deserialize, T: AsRef<[u8]>>(
34 &mut self,
35 command_type: CommandType,
36 payload: T,
37 ) -> Fallible<D> {
38 self.0
39 .write_all(command_type.encode_with(payload).as_slice())
40 .await?;
41 command_type.decode(receive_from_stream(&mut self.0).await?)
42 }
43
44 pub async fn run_command<T: AsRef<str>>(&mut self, payload: T) -> Fallible<Vec<Fallible<()>>> {
46 let outcome: Vec<CommandOutcome> =
47 self.raw_command_with(RunCommand, payload.as_ref()).await?;
48 Ok(outcome.into_iter().map(CommandOutcome::decode).collect())
49 }
50
51 pub async fn get_workspaces(&mut self) -> Fallible<Vec<Workspace>> {
53 self.raw_command(GetWorkspaces).await
54 }
55
56 pub async fn subscribe<T: AsRef<[EventType]>>(mut self, events: T) -> Fallible<EventStream> {
58 let events = serde_json::ser::to_string(events.as_ref())?;
59 let res: Success = self.raw_command_with(Subscribe, events.as_bytes()).await?;
60 if !res.success {
61 return Err(SubscriptionFailed(events));
62 }
63 Ok(EventStream::new(self.0))
64 }
65
66 pub async fn get_outputs(&mut self) -> Fallible<Vec<Output>> {
68 self.raw_command(GetOutputs).await
69 }
70
71 pub async fn get_tree(&mut self) -> Fallible<Node> {
73 self.raw_command(GetTree).await
74 }
75
76 pub async fn get_marks(&mut self) -> Fallible<Vec<String>> {
78 self.raw_command(GetMarks).await
79 }
80
81 pub async fn get_bar_ids(&mut self) -> Fallible<Vec<String>> {
83 self.raw_command(GetBarConfig).await
84 }
85
86 pub async fn get_bar_config<T: AsRef<str>>(&mut self, id: T) -> Fallible<BarConfig> {
88 self.raw_command_with(GetBarConfig, id.as_ref()).await
89 }
90
91 pub async fn get_version(&mut self) -> Fallible<Version> {
93 self.raw_command(GetVersion).await
94 }
95
96 pub async fn get_binding_modes(&mut self) -> Fallible<Vec<String>> {
98 self.raw_command(GetBindingModes).await
99 }
100
101 pub async fn get_config(&mut self) -> Fallible<Config> {
103 self.raw_command(GetConfig).await
104 }
105
106 pub async fn send_tick<T: AsRef<str>>(&mut self, payload: T) -> Fallible<bool> {
108 let res: Success = self.raw_command_with(SendTick, payload.as_ref()).await?;
109 Ok(res.success)
110 }
111
112 pub async fn sync(&mut self) -> Fallible<bool> {
114 let res: Success = self.raw_command(Sync).await?;
115 Ok(res.success)
116 }
117
118 pub async fn get_binding_state(&mut self) -> Fallible<String> {
121 let state: BindingState = self.raw_command(GetBindingState).await?;
122 Ok(state.name)
123 }
124
125 pub async fn get_inputs(&mut self) -> Fallible<Vec<Input>> {
127 self.raw_command(GetInputs).await
128 }
129
130 pub async fn get_seats(&mut self) -> Fallible<Vec<Seat>> {
132 self.raw_command(GetSeats).await
133 }
134}
135
136impl From<Async<UnixStream>> for Connection {
137 fn from(unix_stream: Async<UnixStream>) -> Self {
138 Self(unix_stream)
139 }
140}
141
142impl From<Connection> for Async<UnixStream> {
143 fn from(connection: Connection) -> Self {
144 connection.0
145 }
146}