aboutsummaryrefslogtreecommitdiffstats
path: root/mumlib
diff options
context:
space:
mode:
authorEskil Queseth <eskilq@kth.se>2020-10-17 18:39:36 +0200
committerEskil Queseth <eskilq@kth.se>2020-10-17 18:39:36 +0200
commitc873e4250c58d872763129bff2c0b0e6c91c0a2a (patch)
tree1a55459dd031e5c56ce6ce0db943564aa97baace /mumlib
parentb10d20a20496eb9287975fc9fd9b688d59896031 (diff)
downloadmum-c873e4250c58d872763129bff2c0b0e6c91c0a2a.tar.gz
add pretty printing for mumctl status
Diffstat (limited to 'mumlib')
-rw-r--r--mumlib/src/state.rs94
1 files changed, 94 insertions, 0 deletions
diff --git a/mumlib/src/state.rs b/mumlib/src/state.rs
index 01a31ab..96598de 100644
--- a/mumlib/src/state.rs
+++ b/mumlib/src/state.rs
@@ -1,4 +1,6 @@
use serde::{Deserialize, Serialize};
+use std::fmt::Display;
+use serde::export::Formatter;
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Server {
@@ -18,6 +20,92 @@ pub struct Channel {
pub users: Vec<User>,
}
+impl Channel {
+ pub fn iter(&self) -> Iter<'_> {
+ Iter {
+ me: Some(&self),
+ channel: if self.children.len() > 0 { Some(0) } else { None },
+ channels: self.children.iter().map(|e| e.iter()).collect()
+ }
+ }
+
+ pub fn users_iter(&self) -> UsersIter<'_> {
+ UsersIter {
+ channels: self.children.iter().map(|e| e.users_iter()).collect(),
+ channel: if self.children.len() > 0 { Some(0) } else { None },
+ user: if self.users.len() > 0 { Some(0) } else { None },
+ users: &self.users
+ }
+ }
+}
+
+pub struct Iter<'a> {
+ me: Option<&'a Channel>,
+ channel: Option<usize>,
+ channels: Vec<Iter<'a>>,
+}
+
+impl<'a> Iterator for Iter<'a> {
+ type Item = &'a Channel;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.me.is_some() {
+ self.me.take()
+ } else if let Some(mut c) = self.channel {
+ let mut n = self.channels[c].next();
+ while n.is_none() {
+ c += 1;
+ if c >= self.channels.len() {
+ self.channel = None;
+ return None;
+ }
+ n = self.channels[c].next();
+ }
+ self.channel = Some(c);
+ n
+ } else {
+ None
+ }
+ }
+}
+
+pub struct UsersIter<'a> {
+ channel: Option<usize>,
+ channels: Vec<UsersIter<'a>>,
+ user: Option<usize>,
+ users: &'a [User],
+}
+
+impl<'a> Iterator for UsersIter<'a> {
+ type Item = &'a User;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if let Some(u) = self.user {
+ let ret = Some(&self.users[u]);
+ if u + 1 < self.users.len() {
+ self.user = Some(u + 1);
+ } else {
+ self.user = None;
+ }
+ ret
+ } else if let Some(mut c) = self.channel {
+ let mut n = self.channels[c].next();
+ while n.is_none() {
+ c += 1;
+ if c >= self.channels.len() {
+ self.channel = None;
+ return None;
+ }
+ n = self.channels[c].next();
+ }
+ self.channel = Some(c);
+ n
+ } else {
+ None
+ }
+ }
+}
+
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct User {
pub comment: Option<String>,
@@ -31,4 +119,10 @@ pub struct User {
pub self_deaf: bool, // by self
pub mute: bool, // by admin
pub deaf: bool, // by admin
+}
+
+impl Display for User {
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{}", self.name)
+ }
} \ No newline at end of file