1use derive_more::Display;
5use serde::{Deserialize, Serialize};
6use std::hash::{Hash, Hasher};
7use std::path::PathBuf;
8use std::{env, fmt};
9
10#[derive(
13 Debug, Deserialize, Serialize, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, derive_more::Display,
14)]
15pub struct Address(String);
16impl Address {
17 #[inline(always)]
18 pub(crate) fn fmt_new(address: &str) -> Self {
19 Self("0x".to_owned() + address)
21 }
22 pub fn new<T: ToString>(string: T) -> Self {
24 let str = string.to_string();
25 if str.starts_with("0x") {
26 Self(str)
27 } else {
28 Self("0x".to_owned() + str.as_str())
29 }
30 }
31}
32
33pub trait HyprData {
35 fn get() -> crate::Result<Self>
37 where
38 Self: Sized;
39 #[cfg(any(feature = "async-lite", feature = "tokio"))]
41 async fn get_async() -> crate::Result<Self>
42 where
43 Self: Sized;
44 fn instance_get(instance: &Instance) -> crate::Result<Self>
46 where
47 Self: Sized;
48 #[cfg(any(feature = "async-lite", feature = "tokio"))]
50 async fn instance_get_async(instance: &Instance) -> crate::Result<Self>
51 where
52 Self: Sized;
53}
54
55pub trait HyprDataVec<T>: HyprData {
57 fn to_vec(self) -> Vec<T>;
59}
60
61pub trait HyprDataActive {
63 fn get_active() -> crate::Result<Self>
65 where
66 Self: Sized;
67 #[cfg(any(feature = "async-lite", feature = "tokio"))]
69 async fn get_active_async() -> crate::Result<Self>
70 where
71 Self: Sized;
72 fn instance_get_active(instance: &Instance) -> crate::Result<Self>
74 where
75 Self: Sized;
76 #[cfg(any(feature = "async-lite", feature = "tokio"))]
78 async fn instance_get_active_async(instance: &Instance) -> crate::Result<Self>
79 where
80 Self: Sized;
81}
82
83pub trait HyprDataActiveOptional {
85 fn get_active() -> crate::Result<Option<Self>>
87 where
88 Self: Sized;
89 #[cfg(any(feature = "async-lite", feature = "tokio"))]
91 async fn get_active_async() -> crate::Result<Option<Self>>
92 where
93 Self: Sized;
94 fn instance_get_active(instance: &Instance) -> crate::Result<Option<Self>>
96 where
97 Self: Sized;
98 #[cfg(any(feature = "async-lite", feature = "tokio"))]
100 async fn instance_get_active_async(instance: &Instance) -> crate::Result<Option<Self>>
101 where
102 Self: Sized;
103}
104
105pub type WorkspaceId = i32;
108
109pub type MonitorId = i128;
112
113#[inline]
114fn ser_spec_opt(opt: &Option<String>) -> String {
115 match opt {
116 Some(name) => "special:".to_owned() + name,
117 None => "special".to_owned(),
118 }
119}
120
121#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Display, PartialOrd, Ord)]
123#[serde(untagged)]
124pub enum WorkspaceType {
125 Regular(
127 String,
129 ),
130 #[display("{}", ser_spec_opt(_0))]
132 Special(
133 Option<String>,
135 ),
136}
137
138impl From<&WorkspaceType> for String {
139 fn from(value: &WorkspaceType) -> Self {
140 value.to_string()
141 }
142}
143macro_rules! from {
144 ($($ty:ty),+$(,)?) => {
145 $(
146 impl TryFrom<$ty> for WorkspaceType {
147 type Error = crate::error::HyprError;
148 fn try_from(int: $ty) -> Result<Self, Self::Error> {
149 match int {
150 1.. => Ok(WorkspaceType::Regular(int.to_string())),
151 _ => crate::error::hypr_err!("Conversion error: Unrecognised id"),
152 }
153 }
154 }
155 )+
156 };
157}
158from![u8, u16, u32, u64, usize, i8, i16, i32, i64, isize];
159
160impl Hash for WorkspaceType {
161 fn hash<H: Hasher>(&self, state: &mut H) {
162 match self {
163 WorkspaceType::Regular(name) => name.hash(state),
164 WorkspaceType::Special(value) => match value {
165 Some(name) => name.hash(state),
166 None => "".hash(state),
167 },
168 }
169 }
170}
171
172pub(crate) fn get_hypr_path() -> crate::Result<PathBuf> {
173 let mut buf = if let Some(runtime_path) = env::var_os("XDG_RUNTIME_DIR") {
174 std::path::PathBuf::from(runtime_path)
175 } else if let Ok(uid) = env::var("UID") {
176 std::path::PathBuf::from("/run/user/".to_owned() + &uid)
177 } else {
178 hypr_err!("Could not find XDG_RUNTIME_DIR or UID");
179 };
180 buf.push("hypr");
181 Ok(buf)
182}
183
184#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
186pub enum CommandFlag {
187 #[default]
189 JSON,
190 Empty,
192}
193
194#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
196pub struct CommandContent {
197 pub flag: CommandFlag,
199 pub data: String,
201}
202
203impl CommandContent {
204 pub fn as_bytes(&self) -> Vec<u8> {
216 self.to_string().into_bytes()
217 }
218}
219
220impl fmt::Display for CommandContent {
221 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233 match &self.flag {
234 CommandFlag::JSON => write!(f, "j/{}", &self.data),
235 CommandFlag::Empty => write!(f, "/{}", &self.data),
236 }
237 }
238}
239
240#[macro_export]
247macro_rules! command {
248 ($flag:ident, $($k:tt)*) => {{
249 $crate::shared::CommandContent {
250 flag: $crate::shared::CommandFlag::$flag,
251 data: format!($($k)*),
252 }
253 }};
254}
255use crate::error::hypr_err;
256use crate::instance::Instance;
257pub use command;
258
259#[derive(Debug, Clone, Copy, PartialEq, Eq, derive_more::Display)]
260#[allow(missing_docs)]
261pub enum Mod {
263 #[display("SUPER")]
264 SUPER,
265 #[display("SHIFT")]
266 SHIFT,
267 #[display("ALT")]
268 ALT,
269 #[display("CTRL")]
270 CTRL,
271 #[display("")]
272 NONE,
273}