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
11const MAX_CONNECT_RETRIES: u8 = u8::MAX;
12
13#[derive(Debug)]
14pub struct Connection(Async<UnixStream>);
15
16impl Connection {
17 pub async fn new() -> Fallible<Self> {
19 let socketpath = get_socketpath().await?;
20 let mut retries = 0;
21 loop {
22 let connection = Async::<UnixStream>::connect(socketpath.as_path())
23 .await
24 .map(Self);
25 if matches!(connection.as_ref().map_err(|e| e.kind()), Err(NotConnected))
26 && retries != MAX_CONNECT_RETRIES
27 {
28 Timer::after(Duration::from_millis(100)).await;
29 } else {
30 return Ok(connection?);
31 }
32 retries += 1;
33 }
34 }
35
36 async fn raw_command<D: Deserialize>(&mut self, command_type: CommandType) -> Fallible<D> {
37 self.0.write_all(command_type.encode().as_slice()).await?;
38 command_type.decode(receive_from_stream(&mut self.0).await?)
39 }
40
41 async fn raw_command_with<D: Deserialize, T: AsRef<[u8]>>(
42 &mut self,
43 command_type: CommandType,
44 payload: T,
45 ) -> Fallible<D> {
46 self.0
47 .write_all(command_type.encode_with(payload).as_slice())
48 .await?;
49 command_type.decode(receive_from_stream(&mut self.0).await?)
50 }
51
52 pub async fn run_command<T: AsRef<str>>(&mut self, payload: T) -> Fallible<Vec<Fallible<()>>> {
54 let outcome: Vec<CommandOutcome> =
55 self.raw_command_with(RunCommand, payload.as_ref()).await?;
56 Ok(outcome.into_iter().map(CommandOutcome::decode).collect())
57 }
58
59 pub async fn get_workspaces(&mut self) -> Fallible<Vec<Workspace>> {
61 self.raw_command(GetWorkspaces).await
62 }
63
64 pub async fn subscribe<T: AsRef<[EventType]>>(mut self, events: T) -> Fallible<EventStream> {
66 let events = serde_json::ser::to_string(events.as_ref())?;
67 let res: Success = self.raw_command_with(Subscribe, events.as_bytes()).await?;
68 if !res.success {
69 return Err(SubscriptionFailed(events));
70 }
71 Ok(EventStream::new(self.0))
72 }
73
74 pub async fn get_outputs(&mut self) -> Fallible<Vec<Output>> {
76 self.raw_command(GetOutputs).await
77 }
78
79 pub async fn get_tree(&mut self) -> Fallible<Node> {
81 self.raw_command(GetTree).await
82 }
83
84 pub async fn get_marks(&mut self) -> Fallible<Vec<String>> {
86 self.raw_command(GetMarks).await
87 }
88
89 pub async fn get_bar_ids(&mut self) -> Fallible<Vec<String>> {
91 self.raw_command(GetBarConfig).await
92 }
93
94 pub async fn get_bar_config<T: AsRef<str>>(&mut self, id: T) -> Fallible<BarConfig> {
96 self.raw_command_with(GetBarConfig, id.as_ref()).await
97 }
98
99 pub async fn get_version(&mut self) -> Fallible<Version> {
101 self.raw_command(GetVersion).await
102 }
103
104 pub async fn get_binding_modes(&mut self) -> Fallible<Vec<String>> {
106 self.raw_command(GetBindingModes).await
107 }
108
109 pub async fn get_config(&mut self) -> Fallible<Config> {
111 self.raw_command(GetConfig).await
112 }
113
114 pub async fn send_tick<T: AsRef<str>>(&mut self, payload: T) -> Fallible<bool> {
116 let res: Success = self.raw_command_with(SendTick, payload.as_ref()).await?;
117 Ok(res.success)
118 }
119
120 pub async fn sync(&mut self) -> Fallible<bool> {
122 let res: Success = self.raw_command(Sync).await?;
123 Ok(res.success)
124 }
125
126 pub async fn get_binding_state(&mut self) -> Fallible<String> {
129 let state: BindingState = self.raw_command(GetBindingState).await?;
130 Ok(state.name)
131 }
132
133 pub async fn get_inputs(&mut self) -> Fallible<Vec<Input>> {
135 self.raw_command(GetInputs).await
136 }
137
138 pub async fn get_seats(&mut self) -> Fallible<Vec<Seat>> {
140 self.raw_command(GetSeats).await
141 }
142}
143
144impl From<Async<UnixStream>> for Connection {
145 fn from(unix_stream: Async<UnixStream>) -> Self {
146 Self(unix_stream)
147 }
148}
149
150impl From<Connection> for Async<UnixStream> {
151 fn from(connection: Connection) -> Self {
152 connection.0
153 }
154}