mumlib/
state.rs

1use serde::{Deserialize, Serialize};
2use std::fmt;
3
4/// The state of the currently connected Mumble server.
5#[derive(Clone, Debug, Deserialize, Serialize)]
6pub struct Server {
7    /// State of the currently connected channel.
8    pub channels: Channel,
9    /// The welcome text we received when we connected.
10    pub welcome_text: Option<String>,
11    /// Our username.
12    pub username: String,
13    /// The host (ip:port) of the server.
14    pub host: String,
15}
16
17/// A representation of a channel in a Mumble server.
18#[derive(Clone, Debug, Deserialize, Serialize)]
19pub struct Channel {
20    /// The description of the channel, if set.
21    pub description: Option<String>,
22    /// The maximum number of allowed users in this channel.
23    pub max_users: u32,
24    /// The name of this channel.
25    pub name: String,
26    /// Any children this channel has.
27    pub children: Vec<Channel>,
28    /// This channel's connected users.
29    pub users: Vec<User>,
30
31    links: Vec<Vec<usize>>, //to represent several walks through the tree to find channels its linked to
32}
33
34impl Channel {
35    /// Create a new Channel representation.
36    pub fn new(name: String, description: Option<String>, max_users: u32) -> Self {
37        Self {
38            description,
39            max_users,
40            name,
41            children: Vec::new(),
42            users: Vec::new(),
43
44            links: Vec::new(),
45        }
46    }
47
48    /// Create an iterator over this channel and its children in a [pre-order
49    /// traversal](https://en.wikipedia.org/wiki/Tree_traversal#Pre-order,_NLR)
50    /// which ensures that parent channels are returned before any of its
51    /// children.
52    pub fn iter(&self) -> Iter<'_> {
53        Iter {
54            me: Some(&self),
55            channel: if self.children.is_empty() {
56                None
57            } else {
58                Some(0)
59            },
60            channels: self.children.iter().map(|e| e.iter()).collect(),
61        }
62    }
63
64    /// Create an iterator over this channel and its childrens connected users
65    /// in a pre-order traversal.
66    pub fn users_iter(&self) -> UsersIter<'_> {
67        UsersIter {
68            channels: self.children.iter().map(|e| e.users_iter()).collect(),
69            channel: if self.children.is_empty() {
70                None
71            } else {
72                Some(0)
73            },
74            user: if self.users.is_empty() { None } else { Some(0) },
75            users: &self.users,
76        }
77    }
78}
79
80/// An iterator over channels. Created by [Channel::iter].
81#[derive(Debug)]
82pub struct Iter<'a> {
83    me: Option<&'a Channel>,
84    channel: Option<usize>,
85    channels: Vec<Iter<'a>>,
86}
87
88impl<'a> Iterator for Iter<'a> {
89    type Item = &'a Channel;
90
91    fn next(&mut self) -> Option<Self::Item> {
92        if self.me.is_some() {
93            self.me.take()
94        } else if let Some(mut c) = self.channel {
95            let mut n = self.channels[c].next();
96            while n.is_none() {
97                c += 1;
98                if c >= self.channels.len() {
99                    self.channel = None;
100                    return None;
101                }
102                n = self.channels[c].next();
103            }
104            self.channel = Some(c);
105            n
106        } else {
107            None
108        }
109    }
110}
111
112/// An iterator over users. Created by [Channel::users_iter].
113#[derive(Debug)]
114pub struct UsersIter<'a> {
115    channel: Option<usize>,
116    channels: Vec<UsersIter<'a>>,
117    user: Option<usize>,
118    users: &'a [User],
119}
120
121impl<'a> Iterator for UsersIter<'a> {
122    type Item = &'a User;
123
124    fn next(&mut self) -> Option<Self::Item> {
125        if let Some(u) = self.user {
126            let ret = Some(&self.users[u]);
127            if u + 1 < self.users.len() {
128                self.user = Some(u + 1);
129            } else {
130                self.user = None;
131            }
132            ret
133        } else if let Some(mut c) = self.channel {
134            let mut n = self.channels[c].next();
135            while n.is_none() {
136                c += 1;
137                if c >= self.channels.len() {
138                    self.channel = None;
139                    return None;
140                }
141                n = self.channels[c].next();
142            }
143            self.channel = Some(c);
144            n
145        } else {
146            None
147        }
148    }
149}
150
151#[derive(Clone, Debug, Deserialize, Serialize)]
152pub struct User {
153    pub comment: Option<String>, //TODO not option, empty string instead
154    pub hash: Option<String>,
155    pub name: String,
156    pub priority_speaker: bool,
157    pub recording: bool,
158
159    pub suppress: bool,  // by me
160    pub self_mute: bool, // by self
161    pub self_deaf: bool, // by self
162    pub mute: bool,      // by admin
163    pub deaf: bool,      // by admin
164}
165
166macro_rules! true_to_str {
167    ($condition:expr, $res:expr) => {
168        if $condition {
169            $res
170        } else {
171            ""
172        }
173    };
174}
175
176impl fmt::Display for User {
177    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
178        write!(
179            f,
180            "{} {}{}{}{}{}",
181            self.name,
182            true_to_str!(self.suppress, "s"),
183            true_to_str!(self.self_mute, "M"),
184            true_to_str!(self.self_deaf, "D"),
185            true_to_str!(self.mute, "m"),
186            true_to_str!(self.deaf, "d")
187        )
188    }
189}