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