Skip to content

Commit

Permalink
Merge pull request #188 from JarKz/iterators
Browse files Browse the repository at this point in the history
feat: added a bunch iterators for data structs
  • Loading branch information
yavko committed Mar 15, 2024
2 parents ac18808 + 0a9795a commit 8c9e955
Show file tree
Hide file tree
Showing 3 changed files with 184 additions and 95 deletions.
209 changes: 146 additions & 63 deletions src/data/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,105 +16,188 @@ macro_rules! impl_on {
};
}

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>,
macro_rules! implement_iterators {
(
vector,
name: $name:ident,
iterated_field: $iterated_field:tt,
holding_type: $holding_type:ty,
) => {
impl $name {
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 $name {
/// Get the iterator from the `held` Vec without having to move/clone data
pub fn iter(&self) -> impl Iterator<Item = &$held> {
self.held.iter()
impl IntoIterator for $name {
type Item = $holding_type;

type IntoIter = std::vec::IntoIter<$holding_type>;

fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}

#[async_trait]
impl HyprData for $name {
fn get() -> $crate::Result<Self> {
let data = call_hyprctl_data_cmd($kind);
let deserialized: Vec<$held> = serde_json::from_str(&data)?;
Ok(Self {
held: deserialized,
pos: 0,
})
impl<'a> IntoIterator for &'a $name {
type Item = &'a $holding_type;
type IntoIter = std::slice::Iter<'a, $holding_type>;

fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
async fn get_async() -> $crate::Result<Self> {
let data = call_hyprctl_data_cmd_async($kind).await;
let deserialized: Vec<$held> = serde_json::from_str(&data)?;
Ok(Self {
held: deserialized,
pos: 0,
})
}

impl<'a> IntoIterator for &'a mut $name {
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 Iterator for $name {
type Item = $held;
(
table,
name: $name:ident,
iterated_field: $iterated_field:tt,
key: $key:ty,
value: $value:ty,
) => {
impl $name {
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()
}

fn next(&mut self) -> Option<Self::Item> {
let out = self.held.get(self.pos);
self.pos += 1;
match out {
Some(v) => Some(v.clone()),
None => None,
#[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 {
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 HyprDataVec<$held> for $name {
fn to_vec(self) -> Vec<$held> {
self.held
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()
}
}
};

(sing $name:ident,$kind:path,$held:ty,$c:literal $(, iter_item = $it_it:ty)*) => {
#[doc = $c]
#[derive(Debug)]
pub struct $name($held);
impl<'a> IntoIterator for &'a mut $name {
type Item = (&'a $key, &'a mut $value);
type IntoIter = std::collections::hash_map::IterMut<'a, $key, $value>;

impl $name {
$(
/// Get the iterator from the `held` Vec without having to move/clone data
pub fn iter(&self) -> impl Iterator<Item = $it_it> {
self.0.iter()
}
)*
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<Self> {
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: Vec<$holding_type> = serde_json::from_str(&data)?;
Ok(Self(deserialized))
}
async fn get_async() -> $crate::Result<Self> {
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: Vec<$holding_type> = serde_json::from_str(&data)?;
Ok(Self(deserialized))
}
}

impl HyprDataVec<$holding_type> for $name {
fn to_vec(self) -> Vec<$holding_type> {
self.0
}
}
};

(p $name:ident,$kind:path,$caller:expr,$held:ty,$c:literal) => {
#[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);
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() -> HResult<Self> {
let data = call_hyprctl_data_cmd($kind);
Ok(Self($caller(data)?))
fn get() -> $crate::Result<Self> {
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() -> HResult<Self> {
let data = call_hyprctl_data_cmd_async($kind).await;
Ok(Self($caller(data)?))

async fn get_async() -> $crate::Result<Self> {
let data = call_hyprctl_data_cmd_async($cmd_kind).await;
let deserialized: HashMap<$key, $value> = serde_json::from_str(&data)?;
Ok(Self(deserialized))
}
}
};
Expand Down
68 changes: 37 additions & 31 deletions src/data/regular.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,16 @@ pub struct Monitor {
#[async_trait]
impl HyprDataActive for Monitor {
fn get_active() -> crate::Result<Self> {
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<Self> {
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?")
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -307,19 +310,21 @@ pub struct LayerDisplay {
pub levels: HashMap<String, Vec<LayerClient>>,
}

impl LayerDisplay {
/// Returns an iterator over the levels map
pub fn iter(&self) -> impl Iterator<Item = (&String, &Vec<LayerClient>)> {
self.levels.iter()
}
}
implement_iterators!(
table,
name: LayerDisplay,
iterated_field: levels,
key: String,
value: Vec<LayerClient>,
);

create_data_struct!(
sing Layers,
DataCommands::Layers,
HashMap<String, LayerDisplay>,
"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
Expand Down Expand Up @@ -458,10 +463,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
Expand Down
2 changes: 1 addition & 1 deletion src/event_listener/mutable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,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?"),
},
Expand Down

0 comments on commit 8c9e955

Please sign in to comment.