aboutsummaryrefslogtreecommitdiffstats
path: root/mumlib/src
diff options
context:
space:
mode:
Diffstat (limited to 'mumlib/src')
-rw-r--r--mumlib/src/command.rs10
-rw-r--r--mumlib/src/error.rs6
-rw-r--r--mumlib/src/lib.rs2
-rw-r--r--mumlib/src/state.rs290
4 files changed, 107 insertions, 201 deletions
diff --git a/mumlib/src/command.rs b/mumlib/src/command.rs
index b27d3ca..b4ab07a 100644
--- a/mumlib/src/command.rs
+++ b/mumlib/src/command.rs
@@ -1,7 +1,6 @@
use crate::state::{Channel, Server};
use serde::{Deserialize, Serialize};
-use std::collections::HashMap;
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum Command {
@@ -22,11 +21,6 @@ pub enum Command {
#[derive(Debug, Deserialize, Serialize)]
pub enum CommandResponse {
- ChannelList {
- channels: HashMap<u32, Channel>,
- },
- Status {
- username: Option<String>,
- server_state: Server,
- },
+ ChannelList { channels: Channel },
+ Status { server_state: Server },
}
diff --git a/mumlib/src/error.rs b/mumlib/src/error.rs
index 6c66c1f..a4c6dcb 100644
--- a/mumlib/src/error.rs
+++ b/mumlib/src/error.rs
@@ -1,6 +1,6 @@
-use serde::{Serialize, Deserialize};
-use std::fmt::Display;
use serde::export::Formatter;
+use serde::{Deserialize, Serialize};
+use std::fmt::Display;
pub type Result<T> = std::result::Result<T, Error>;
@@ -37,4 +37,4 @@ impl Display for ChannelIdentifierError {
ChannelIdentifierError::Ambiguous => write!(f, "Ambiguous channel identifier"),
}
}
-} \ No newline at end of file
+}
diff --git a/mumlib/src/lib.rs b/mumlib/src/lib.rs
index b77653c..d989a7e 100644
--- a/mumlib/src/lib.rs
+++ b/mumlib/src/lib.rs
@@ -1,6 +1,6 @@
pub mod command;
-pub mod state;
pub mod error;
+pub mod state;
use colored::*;
use log::*;
diff --git a/mumlib/src/state.rs b/mumlib/src/state.rs
index 51fb492..b09726e 100644
--- a/mumlib/src/state.rs
+++ b/mumlib/src/state.rs
@@ -1,224 +1,136 @@
-use log::*;
-use mumble_protocol::control::msgs;
+use serde::export::Formatter;
use serde::{Deserialize, Serialize};
-use std::collections::hash_map::Entry;
-use std::collections::HashMap;
+use std::fmt::Display;
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Server {
- channels: HashMap<u32, Channel>,
- users: HashMap<u32, User>,
+ pub channels: Channel,
pub welcome_text: Option<String>,
-}
-
-impl Server {
- pub fn new() -> Self {
- Self {
- channels: HashMap::new(),
- users: HashMap::new(),
- welcome_text: None,
- }
- }
-
- pub fn parse_server_sync(&mut self, mut msg: msgs::ServerSync) {
- if msg.has_welcome_text() {
- self.welcome_text = Some(msg.take_welcome_text());
- }
- }
-
- pub fn parse_channel_state(&mut self, msg: msgs::ChannelState) {
- if !msg.has_channel_id() {
- warn!("Can't parse channel state without channel id");
- return;
- }
- match self.channels.entry(msg.get_channel_id()) {
- Entry::Vacant(e) => {
- e.insert(Channel::new(msg));
- }
- Entry::Occupied(mut e) => e.get_mut().parse_channel_state(msg),
- }
- }
-
- pub fn parse_channel_remove(&mut self, msg: msgs::ChannelRemove) {
- if !msg.has_channel_id() {
- warn!("Can't parse channel remove without channel id");
- return;
- }
- match self.channels.entry(msg.get_channel_id()) {
- Entry::Vacant(_) => {
- warn!("Attempted to remove channel that doesn't exist");
- }
- Entry::Occupied(e) => {
- e.remove();
- }
- }
- }
-
- pub fn parse_user_state(&mut self, msg: msgs::UserState) {
- if !msg.has_session() {
- warn!("Can't parse user state without session");
- return;
- }
- match self.users.entry(msg.get_session()) {
- Entry::Vacant(e) => {
- e.insert(User::new(msg));
- }
- Entry::Occupied(mut e) => e.get_mut().parse_user_state(msg),
- }
- }
-
- pub fn channels(&self) -> &HashMap<u32, Channel> {
- &self.channels
- }
-
- pub fn users(&self) -> &HashMap<u32, User> {
- &self.users
- }
+ pub username: String,
+ pub host: String,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Channel {
- description: Option<String>,
- links: Vec<u32>,
- max_users: u32,
- name: String,
- parent: Option<u32>,
- position: i32,
+ pub description: Option<String>,
+ pub links: Vec<Vec<usize>>, //to represent several walks through the tree to find channels its linked to
+ pub max_users: u32,
+ pub name: String,
+ pub children: Vec<Channel>,
+ pub users: Vec<User>,
}
impl Channel {
- pub fn new(mut msg: msgs::ChannelState) -> Self {
- Self {
- description: if msg.has_description() {
- Some(msg.take_description())
+ pub fn iter(&self) -> Iter<'_> {
+ Iter {
+ me: Some(&self),
+ channel: if self.children.len() > 0 {
+ Some(0)
} else {
None
},
- links: Vec::new(),
- max_users: msg.get_max_users(),
- name: msg.take_name(),
- parent: if msg.has_parent() {
- Some(msg.get_parent())
- } else {
- None
- },
- position: msg.get_position(),
+ channels: self.children.iter().map(|e| e.iter()).collect(),
}
}
- pub fn parse_channel_state(&mut self, mut msg: msgs::ChannelState) {
- if msg.has_description() {
- self.description = Some(msg.take_description());
- }
- self.links = msg.take_links();
- if msg.has_max_users() {
- self.max_users = msg.get_max_users();
- }
- if msg.has_name() {
- self.name = msg.take_name();
- }
- if msg.has_parent() {
- self.parent = Some(msg.get_parent());
- }
- if msg.has_position() {
- self.position = msg.get_position();
+ 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 fn name(&self) -> &str {
- &self.name
- }
+pub struct Iter<'a> {
+ me: Option<&'a Channel>,
+ channel: Option<usize>,
+ channels: Vec<Iter<'a>>,
+}
- pub fn path(&self, channels: &HashMap<u32, Channel>) -> String {
- match &self.parent {
- Some(t) => format!("{}/{}", channels.get(t).unwrap().path(channels), self.name),
- None => self.name.clone(),
+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
}
}
}
-#[derive(Clone, Debug, Deserialize, Serialize)]
-pub struct User {
- channel: u32,
- comment: Option<String>,
- hash: Option<String>,
- name: String,
- priority_speaker: bool,
- recording: bool,
-
- suppress: bool, // by me
- self_mute: bool, // by self
- self_deaf: bool, // by self
- mute: bool, // by admin
- deaf: bool, // by admin
+pub struct UsersIter<'a> {
+ channel: Option<usize>,
+ channels: Vec<UsersIter<'a>>,
+ user: Option<usize>,
+ users: &'a [User],
}
-impl User {
- pub fn new(mut msg: msgs::UserState) -> Self {
- Self {
- channel: msg.get_channel_id(),
- comment: if msg.has_comment() {
- Some(msg.take_comment())
- } else {
- None
- },
- hash: if msg.has_hash() {
- Some(msg.take_hash())
- } else {
- None
- },
- name: msg.take_name(),
- priority_speaker: msg.has_priority_speaker() && msg.get_priority_speaker(),
- recording: msg.has_recording() && msg.get_recording(),
- suppress: msg.has_suppress() && msg.get_suppress(),
- self_mute: msg.has_self_mute() && msg.get_self_mute(),
- self_deaf: msg.has_self_deaf() && msg.get_self_deaf(),
- mute: msg.has_mute() && msg.get_mute(),
- deaf: msg.has_deaf() && msg.get_deaf(),
- }
- }
+impl<'a> Iterator for UsersIter<'a> {
+ type Item = &'a User;
- pub fn parse_user_state(&mut self, mut msg: msgs::UserState) {
- if msg.has_channel_id() {
- self.channel = msg.get_channel_id();
- }
- if msg.has_comment() {
- self.comment = Some(msg.take_comment());
- }
- if msg.has_hash() {
- self.hash = Some(msg.take_hash());
- }
- if msg.has_name() {
- self.name = msg.take_name();
- }
- if msg.has_priority_speaker() {
- self.priority_speaker = msg.get_priority_speaker();
- }
- if msg.has_recording() {
- self.recording = msg.get_recording();
- }
- if msg.has_suppress() {
- self.suppress = msg.get_suppress();
- }
- if msg.has_self_mute() {
- self.self_mute = msg.get_self_mute();
- }
- if msg.has_self_deaf() {
- self.self_deaf = msg.get_self_deaf();
- }
- if msg.has_mute() {
- self.mute = msg.get_mute();
- }
- if msg.has_deaf() {
- self.deaf = msg.get_deaf();
+ 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
}
}
+}
- pub fn name(&self) -> &str {
- &self.name
- }
+#[derive(Clone, Debug, Deserialize, Serialize)]
+pub struct User {
+ pub comment: Option<String>,
+ pub hash: Option<String>,
+ pub name: String,
+ pub priority_speaker: bool,
+ pub recording: bool,
+
+ pub suppress: bool, // by me
+ pub self_mute: bool, // by self
+ pub self_deaf: bool, // by self
+ pub mute: bool, // by admin
+ pub deaf: bool, // by admin
+}
- pub fn channel(&self) -> u32 {
- self.channel
+impl Display for User {
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{}", self.name)
}
}