From 39162b90018050c9ba0c3c1f03a0637cd3d64f0f Mon Sep 17 00:00:00 2001 From: Pavel Date: Tue, 12 Mar 2024 16:36:37 +0300 Subject: [PATCH 1/6] feat: implemented more iterators for data structs --- src/data/macros.rs | 59 +++++++++++++++++++++-------------- src/data/regular.rs | 8 ++--- src/event_listener/mutable.rs | 2 +- 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/data/macros.rs b/src/data/macros.rs index e682d1f..5c8bff3 100644 --- a/src/data/macros.rs +++ b/src/data/macros.rs @@ -20,15 +20,17 @@ macro_rules! create_data_struct { (vec $name:ident,$kind:path,$held:ty,$c:literal) => { #[doc = $c] #[derive(Debug, Clone)] - pub struct $name { - pos: usize, - held: Vec<$held>, - } + pub struct $name(Vec<$held>); impl $name { - /// Get the iterator from the `held` Vec without having to move/clone data - pub fn iter(&self) -> impl Iterator { - self.held.iter() + /// Get the iterator by references of monitors. + pub fn iter(&self) -> std::slice::Iter<$held> { + self.0.iter() + } + + /// Get the iterator by mutable references of monitors. + pub fn iter_mut(&mut self) -> std::slice::IterMut<$held> { + self.0.iter_mut() } } @@ -37,37 +39,46 @@ macro_rules! create_data_struct { fn get() -> $crate::Result { let data = call_hyprctl_data_cmd($kind); let deserialized: Vec<$held> = serde_json::from_str(&data)?; - Ok(Self { - held: deserialized, - pos: 0, - }) + Ok(Self(deserialized)) } async fn get_async() -> $crate::Result { let data = call_hyprctl_data_cmd_async($kind).await; let deserialized: Vec<$held> = serde_json::from_str(&data)?; - Ok(Self { - held: deserialized, - pos: 0, - }) + Ok(Self(deserialized)) } } - impl Iterator for $name { + impl IntoIterator for $name { type Item = $held; - fn next(&mut self) -> Option { - let out = self.held.get(self.pos); - self.pos += 1; - match out { - Some(v) => Some(v.clone()), - None => None, - } + type IntoIter = std::vec::IntoIter<$held>; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } + } + + impl<'a> IntoIterator for &'a $name { + type Item = &'a $held; + type IntoIter = std::slice::Iter<'a, $held>; + + fn into_iter(self) -> Self::IntoIter { + self.0.iter() + } + } + + impl<'a> IntoIterator for &'a mut $name { + type Item = &'a mut $held; + type IntoIter = std::slice::IterMut<'a, $held>; + + fn into_iter(self) -> Self::IntoIter { + self.0.iter_mut() } } impl HyprDataVec<$held> for $name { fn to_vec(self) -> Vec<$held> { - self.held + self.0 } } }; diff --git a/src/data/regular.rs b/src/data/regular.rs index be2aedb..cc0448b 100644 --- a/src/data/regular.rs +++ b/src/data/regular.rs @@ -131,16 +131,16 @@ pub struct Monitor { #[async_trait] impl HyprDataActive for Monitor { fn get_active() -> crate::Result { - let mut all = Monitors::get()?; - if let Some(it) = all.find(|item| item.focused) { + let all = Monitors::get()?; + if let Some(it) = all.into_iter().find(|item| item.focused) { Ok(it) } else { panic!("No active monitor?") } } async fn get_active_async() -> crate::Result { - let mut all = Monitors::get_async().await?; - if let Some(it) = all.find(|item| item.focused) { + let all = Monitors::get_async().await?; + if let Some(it) = all.into_iter().find(|item| item.focused) { Ok(it) } else { panic!("No active monitor?") diff --git a/src/event_listener/mutable.rs b/src/event_listener/mutable.rs index da2b443..910f82d 100644 --- a/src/event_listener/mutable.rs +++ b/src/event_listener/mutable.rs @@ -134,7 +134,7 @@ impl EventListener { Err(e) => panic!("Error parsing data whith serde: {e}"), }, active_monitor: match Monitors::get() { - Ok(mut monitors) => match monitors.find(|item| item.focused) { + Ok(monitors) => match monitors.into_iter().find(|item| item.focused) { Some(mon) => mon.name, None => panic!("No active monitor?"), }, From ade33f5cc99fe5d4a121d4f34d9b001dcd90be2d Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 13 Mar 2024 09:05:19 +0300 Subject: [PATCH 2/6] refactor: changed sing to table macros --- src/data/macros.rs | 31 +++++++++++++++---------------- src/data/regular.rs | 11 ++++++----- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/data/macros.rs b/src/data/macros.rs index 5c8bff3..60970af 100644 --- a/src/data/macros.rs +++ b/src/data/macros.rs @@ -83,30 +83,29 @@ macro_rules! create_data_struct { } }; - (sing $name:ident,$kind:path,$held:ty,$c:literal $(, iter_item = $it_it:ty)*) => { - #[doc = $c] + ( + table, + name: $name:ident, + command: $cmd_kind:path, + key: $key:ty, + value: $value:ty, + doc: $doc:literal + ) => { + #[doc = $doc] #[derive(Debug)] - pub struct $name($held); - - impl $name { - $( - /// Get the iterator from the `held` Vec without having to move/clone data - pub fn iter(&self) -> impl Iterator { - self.0.iter() - } - )* - } + pub struct $name(HashMap<$key, $value>); #[async_trait] impl HyprData for $name { fn get() -> $crate::Result { - let data = call_hyprctl_data_cmd($kind); - let deserialized: $held = serde_json::from_str(&data)?; + let data = call_hyprctl_data_cmd($cmd_kind); + let deserialized: HashMap<$key, $value> = serde_json::from_str(&data)?; Ok(Self(deserialized)) } + async fn get_async() -> $crate::Result { - let data = call_hyprctl_data_cmd_async($kind).await; - let deserialized: $held = serde_json::from_str(&data)?; + let data = call_hyprctl_data_cmd_async($cmd_kind).await; + let deserialized: HashMap<$key, $value> = serde_json::from_str(&data)?; Ok(Self(deserialized)) } } diff --git a/src/data/regular.rs b/src/data/regular.rs index cc0448b..21d6f8b 100644 --- a/src/data/regular.rs +++ b/src/data/regular.rs @@ -315,11 +315,12 @@ impl LayerDisplay { } create_data_struct!( - sing Layers, - DataCommands::Layers, - HashMap, - "This struct holds a hashmap of all current displays, and their layer surfaces", - iter_item = (&String, &LayerDisplay) + table, + name: Layers, + command: DataCommands::Layers, + key: String, + value: LayerDisplay, + doc: "This struct holds a hashmap of all current displays, and their layer surfaces" ); /// This struct holds information about a mouse device From 076351bb61b9fbdac9998440edf2c4594b3a2b0b Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 13 Mar 2024 09:23:31 +0300 Subject: [PATCH 3/6] refactor: changed datastruct macros for vectors --- src/data/macros.rs | 40 +++++++++++++++++++++++----------------- src/data/regular.rs | 36 ++++++++++++++++++++---------------- 2 files changed, 43 insertions(+), 33 deletions(-) diff --git a/src/data/macros.rs b/src/data/macros.rs index 60970af..47189d9 100644 --- a/src/data/macros.rs +++ b/src/data/macros.rs @@ -17,19 +17,25 @@ macro_rules! impl_on { } macro_rules! create_data_struct { - (vec $name:ident,$kind:path,$held:ty,$c:literal) => { - #[doc = $c] + ( + vector, + name: $name:ident, + command: $cmd_kind:path, + holding_type: $holding_type:ty, + doc: $doc:literal + ) => { + #[doc = $doc] #[derive(Debug, Clone)] - pub struct $name(Vec<$held>); + pub struct $name(Vec<$holding_type>); impl $name { /// Get the iterator by references of monitors. - pub fn iter(&self) -> std::slice::Iter<$held> { + pub fn iter(&self) -> std::slice::Iter<$holding_type> { self.0.iter() } /// Get the iterator by mutable references of monitors. - pub fn iter_mut(&mut self) -> std::slice::IterMut<$held> { + pub fn iter_mut(&mut self) -> std::slice::IterMut<$holding_type> { self.0.iter_mut() } } @@ -37,21 +43,21 @@ macro_rules! create_data_struct { #[async_trait] impl HyprData for $name { fn get() -> $crate::Result { - let data = call_hyprctl_data_cmd($kind); - let deserialized: Vec<$held> = serde_json::from_str(&data)?; + let data = call_hyprctl_data_cmd($cmd_kind); + let deserialized: Vec<$holding_type> = serde_json::from_str(&data)?; Ok(Self(deserialized)) } async fn get_async() -> $crate::Result { - let data = call_hyprctl_data_cmd_async($kind).await; - let deserialized: Vec<$held> = serde_json::from_str(&data)?; + let data = call_hyprctl_data_cmd_async($cmd_kind).await; + let deserialized: Vec<$holding_type> = serde_json::from_str(&data)?; Ok(Self(deserialized)) } } impl IntoIterator for $name { - type Item = $held; + type Item = $holding_type; - type IntoIter = std::vec::IntoIter<$held>; + type IntoIter = std::vec::IntoIter<$holding_type>; fn into_iter(self) -> Self::IntoIter { self.0.into_iter() @@ -59,8 +65,8 @@ macro_rules! create_data_struct { } impl<'a> IntoIterator for &'a $name { - type Item = &'a $held; - type IntoIter = std::slice::Iter<'a, $held>; + type Item = &'a $holding_type; + type IntoIter = std::slice::Iter<'a, $holding_type>; fn into_iter(self) -> Self::IntoIter { self.0.iter() @@ -68,16 +74,16 @@ macro_rules! create_data_struct { } impl<'a> IntoIterator for &'a mut $name { - type Item = &'a mut $held; - type IntoIter = std::slice::IterMut<'a, $held>; + type Item = &'a mut $holding_type; + type IntoIter = std::slice::IterMut<'a, $holding_type>; fn into_iter(self) -> Self::IntoIter { self.0.iter_mut() } } - impl HyprDataVec<$held> for $name { - fn to_vec(self) -> Vec<$held> { + impl HyprDataVec<$holding_type> for $name { + fn to_vec(self) -> Vec<$holding_type> { self.0 } } diff --git a/src/data/regular.rs b/src/data/regular.rs index 21d6f8b..ca8937b 100644 --- a/src/data/regular.rs +++ b/src/data/regular.rs @@ -149,10 +149,11 @@ impl HyprDataActive for Monitor { } create_data_struct!( - vec Monitors, - DataCommands::Monitors, - Monitor, - "This struct holds a vector of monitors" + vector, + name: Monitors, + command: DataCommands::Monitors, + holding_type: Monitor, + doc: "This struct holds a vector of monitors" ); /// This struct holds information for a workspace @@ -195,10 +196,11 @@ impl HyprDataActive for Workspace { } create_data_struct!( - vec Workspaces, - DataCommands::Workspaces, - Workspace, - "This type provides a vector of workspaces" + vector, + name: Workspaces, + command: DataCommands::Workspaces, + holding_type: Workspace, + doc: "This type provides a vector of workspaces" ); /// This struct holds information for a client/window @@ -277,10 +279,11 @@ impl HyprDataActiveOptional for Client { } create_data_struct!( - vec Clients, - DataCommands::Clients, - Client, - "This struct holds a vector of clients" + vector, + name: Clients, + command: DataCommands::Clients, + holding_type: Client, + doc: "This struct holds a vector of clients" ); /// This struct holds information about a layer surface/client @@ -459,10 +462,11 @@ pub struct Bind { } create_data_struct!( - vec Binds, - DataCommands::Binds, - Bind, - "This struct holds a vector of binds" + vector, + name: Binds, + command: DataCommands::Binds, + holding_type: Bind, + doc: "This struct holds a vector of binds" ); /// Animation styles From e2c1dd2943189cf6a34287ac513a15efc9ebdeb3 Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 13 Mar 2024 09:46:42 +0300 Subject: [PATCH 4/6] feat: added iterators for table data structures --- src/data/macros.rs | 119 ++++++++++++++++++++++++++++++++++++-------- src/data/regular.rs | 13 ++--- 2 files changed, 105 insertions(+), 27 deletions(-) diff --git a/src/data/macros.rs b/src/data/macros.rs index 47189d9..31539e6 100644 --- a/src/data/macros.rs +++ b/src/data/macros.rs @@ -16,18 +16,13 @@ macro_rules! impl_on { }; } -macro_rules! create_data_struct { +macro_rules! implement_iterators { ( vector, name: $name:ident, - command: $cmd_kind:path, + iterated_field: $iterated_field:tt, holding_type: $holding_type:ty, - doc: $doc:literal ) => { - #[doc = $doc] - #[derive(Debug, Clone)] - pub struct $name(Vec<$holding_type>); - impl $name { /// Get the iterator by references of monitors. pub fn iter(&self) -> std::slice::Iter<$holding_type> { @@ -40,20 +35,6 @@ macro_rules! create_data_struct { } } - #[async_trait] - impl HyprData for $name { - fn get() -> $crate::Result { - let data = call_hyprctl_data_cmd($cmd_kind); - let deserialized: Vec<$holding_type> = serde_json::from_str(&data)?; - Ok(Self(deserialized)) - } - async fn get_async() -> $crate::Result { - let data = call_hyprctl_data_cmd_async($cmd_kind).await; - let deserialized: Vec<$holding_type> = serde_json::from_str(&data)?; - Ok(Self(deserialized)) - } - } - impl IntoIterator for $name { type Item = $holding_type; @@ -81,6 +62,94 @@ macro_rules! create_data_struct { self.0.iter_mut() } } + }; + + ( + table, + name: $name:ident, + iterated_field: $iterated_field:tt, + key: $key:ty, + value: $value:ty, + ) => { + impl $name { + pub fn iter(&self) -> std::collections::hash_map::Iter<$key, $value> { + self.$iterated_field.iter() + } + + pub fn iter_mut(&mut self) -> std::collections::hash_map::IterMut<$key, $value> { + self.$iterated_field.iter_mut() + } + + pub fn into_keys(self) -> std::collections::hash_map::IntoKeys<$key, $value> { + self.$iterated_field.into_keys() + } + + pub fn into_values(self) -> std::collections::hash_map::IntoValues<$key, $value> { + self.$iterated_field.into_values() + } + } + + impl IntoIterator for $name { + type Item = ($key, $value); + type IntoIter = std::collections::hash_map::IntoIter<$key, $value>; + + fn into_iter(self) -> Self::IntoIter { + self.$iterated_field.into_iter() + } + } + + impl<'a> IntoIterator for &'a $name { + type Item = (&'a $key, &'a $value); + type IntoIter = std::collections::hash_map::Iter<'a, $key, $value>; + + fn into_iter(self) -> Self::IntoIter { + self.$iterated_field.iter() + } + } + + impl<'a> IntoIterator for &'a mut $name { + type Item = (&'a $key, &'a mut $value); + type IntoIter = std::collections::hash_map::IterMut<'a, $key, $value>; + + fn into_iter(self) -> Self::IntoIter { + self.$iterated_field.iter_mut() + } + } + } +} + +macro_rules! create_data_struct { + ( + vector, + name: $name:ident, + command: $cmd_kind:path, + holding_type: $holding_type:ty, + doc: $doc:literal + ) => { + #[doc = $doc] + #[derive(Debug, Clone)] + pub struct $name(Vec<$holding_type>); + + implement_iterators!( + vector, + name: $name, + iterated_field: 0, + holding_type: $holding_type, + ); + + #[async_trait] + impl HyprData for $name { + fn get() -> $crate::Result { + let data = call_hyprctl_data_cmd($cmd_kind); + let deserialized: Vec<$holding_type> = serde_json::from_str(&data)?; + Ok(Self(deserialized)) + } + async fn get_async() -> $crate::Result { + let data = call_hyprctl_data_cmd_async($cmd_kind).await; + let deserialized: Vec<$holding_type> = serde_json::from_str(&data)?; + Ok(Self(deserialized)) + } + } impl HyprDataVec<$holding_type> for $name { fn to_vec(self) -> Vec<$holding_type> { @@ -101,6 +170,14 @@ macro_rules! create_data_struct { #[derive(Debug)] pub struct $name(HashMap<$key, $value>); + implement_iterators!( + table, + name: $name, + iterated_field: 0, + key: $key, + value: $value, + ); + #[async_trait] impl HyprData for $name { fn get() -> $crate::Result { diff --git a/src/data/regular.rs b/src/data/regular.rs index ca8937b..b78fa25 100644 --- a/src/data/regular.rs +++ b/src/data/regular.rs @@ -310,12 +310,13 @@ pub struct LayerDisplay { pub levels: HashMap>, } -impl LayerDisplay { - /// Returns an iterator over the levels map - pub fn iter(&self) -> impl Iterator)> { - self.levels.iter() - } -} +implement_iterators!( + table, + name: LayerDisplay, + iterated_field: levels, + key: String, + value: Vec, +); create_data_struct!( table, From 65d087b8e545af3800c75bc3506b7ee7a678906f Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 13 Mar 2024 10:33:22 +0300 Subject: [PATCH 5/6] docs: added documentation for iter, iter_mut... --- src/data/macros.rs | 56 ++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/src/data/macros.rs b/src/data/macros.rs index 31539e6..d5aded5 100644 --- a/src/data/macros.rs +++ b/src/data/macros.rs @@ -24,15 +24,17 @@ macro_rules! implement_iterators { holding_type: $holding_type:ty, ) => { impl $name { - /// Get the iterator by references of monitors. - pub fn iter(&self) -> std::slice::Iter<$holding_type> { - self.0.iter() - } - - /// Get the iterator by mutable references of monitors. - pub fn iter_mut(&mut self) -> std::slice::IterMut<$holding_type> { - self.0.iter_mut() - } + paste!( + #[doc = "Creates the iterator by references of `" $name "`."] + pub fn iter(&self) -> std::slice::Iter<$holding_type> { + self.0.iter() + } + + #[doc = "Creates the iterator by mutable references of " $name "`."] + pub fn iter_mut(&mut self) -> std::slice::IterMut<$holding_type> { + self.0.iter_mut() + } + ); } impl IntoIterator for $name { @@ -72,21 +74,27 @@ macro_rules! implement_iterators { value: $value:ty, ) => { impl $name { - pub fn iter(&self) -> std::collections::hash_map::Iter<$key, $value> { - self.$iterated_field.iter() - } - - pub fn iter_mut(&mut self) -> std::collections::hash_map::IterMut<$key, $value> { - self.$iterated_field.iter_mut() - } - - pub fn into_keys(self) -> std::collections::hash_map::IntoKeys<$key, $value> { - self.$iterated_field.into_keys() - } - - pub fn into_values(self) -> std::collections::hash_map::IntoValues<$key, $value> { - self.$iterated_field.into_values() - } + paste!( + #[doc = "Creates the iterator of map by references of " $name] + pub fn iter(&self) -> std::collections::hash_map::Iter<$key, $value> { + self.$iterated_field.iter() + } + + #[doc = "Creates the iterator of map by mutable references of `" $name "`."] + pub fn iter_mut(&mut self) -> std::collections::hash_map::IterMut<$key, $value> { + self.$iterated_field.iter_mut() + } + + #[doc = "Creates the consuming iterator by keys with type `" $key "` of `" $name "`."] + pub fn into_keys(self) -> std::collections::hash_map::IntoKeys<$key, $value> { + self.$iterated_field.into_keys() + } + + #[doc = "Creates the consuming iterator by values of `" $name "`."] + pub fn into_values(self) -> std::collections::hash_map::IntoValues<$key, $value> { + self.$iterated_field.into_values() + } + ); } impl IntoIterator for $name { From 0a9795aba3dc0e07d13902b12543b11d4676969e Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 13 Mar 2024 10:35:37 +0300 Subject: [PATCH 6/6] refactor: removed useless macro match branch --- src/data/macros.rs | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/data/macros.rs b/src/data/macros.rs index d5aded5..f192ea0 100644 --- a/src/data/macros.rs +++ b/src/data/macros.rs @@ -201,22 +201,4 @@ macro_rules! create_data_struct { } } }; - - (p $name:ident,$kind:path,$caller:expr,$held:ty,$c:literal) => { - #[doc = $c] - #[derive(Debug)] - pub struct $name($held); - - #[async_trait] - impl HyprData for $name { - fn get() -> HResult { - let data = call_hyprctl_data_cmd($kind); - Ok(Self($caller(data)?)) - } - async fn get_async() -> HResult { - let data = call_hyprctl_data_cmd_async($kind).await; - Ok(Self($caller(data)?)) - } - } - }; }