time::{self, Duration},
};
+use anyhow::{Context, Result};
use itertools::Itertools;
use json::{self, JsonValue};
use rsevents::{AutoResetEvent, Awaitable, EventState};
ice
}
- pub fn get_users(&mut self) -> Vec<User> {
+ pub fn get_users(&mut self) -> Result<Vec<User>> {
let now = time::Instant::now();
if self.cached_users_timestamp + CACHED_VALUES_DURATION > now {
- self.cached_users.clone()
+ Ok(self.cached_users.clone())
} else {
- let mut stream = TcpStream::connect("127.0.0.1:4978").unwrap();
+ let mut stream = TcpStream::connect("127.0.0.1:4978")?;
let id: u32 = 1;
let length: u32 = 0;
let mut buffer = [0u8; 8];
buffer[0..4].copy_from_slice(&id.to_ne_bytes());
buffer[4..8].copy_from_slice(&length.to_ne_bytes());
- stream.write(&buffer).unwrap();
+ stream.write(&buffer)?;
let mut id_bytes = [0u8; 4];
let mut length_bytes = [0u8; 4];
- stream.read(&mut id_bytes).unwrap();
- stream.read(&mut length_bytes).unwrap();
+ stream.read(&mut id_bytes)?;
+ stream.read(&mut length_bytes)?;
let id = u32::from_ne_bytes(id_bytes);
// Response id must be 2.
let length = u32::from_ne_bytes(length_bytes);
let mut payload = vec![0u8; length as usize];
- stream.read_exact(&mut payload).unwrap();
- let json_str = from_utf8(&payload).unwrap();
- let json = json::parse(json_str).unwrap();
+ stream.read_exact(&mut payload)?;
+ let json_str = from_utf8(&payload)?;
+ let json = json::parse(json_str)?;
// println!("id: {}, length: {}, json: {:?}", id, length, json); // Debug.
let user_json = &json[i];
users.push(User {
- name: user_json["username"].as_str().unwrap().to_string(),
- channel_path: user_json["channelPath"].as_str().unwrap().to_string(),
+ name: user_json["username"]
+ .as_str()
+ .context("JSON: username field missing")?
+ .to_string(),
+ channel_path: user_json["channelPath"]
+ .as_str()
+ .context("JSON: username field missing")?
+ .to_string(),
// TODO: a bit ugly.
channel_path_positions: match &user_json["channelPathPositions"] {
- JsonValue::Array(array) => {
- array.iter().map(|v| v.as_i32().unwrap()).collect_vec()
- }
+ JsonValue::Array(array) => array
+ .iter()
+ .map(|v| v.as_i32().unwrap_or_default())
+ .collect_vec(),
_ => vec![],
},
- self_mute: user_json["selfMute"].as_bool().unwrap(),
- self_deaf: user_json["selfDeaf"].as_bool().unwrap(),
+ self_mute: user_json["selfMute"]
+ .as_bool()
+ .context("JSON: selfMute field missing")?,
+ self_deaf: user_json["selfDeaf"]
+ .as_bool()
+ .context("JSON: selfMute field missing")?,
});
}
self.cached_users = users.clone();
self.cached_users_timestamp = time::Instant::now();
- users
+ Ok(users)
}
}
}
}
async fn root(State(ice): State<Arc<Mutex<ice::Ice>>>) -> impl IntoResponse {
- let users = ice.lock().unwrap().get_users();
-
- let mut channels = Vec::<Channel>::new();
- 'next_user: for u in &users {
- for c in &mut channels {
- if c.path == u.channel_path {
- c.users.push(User::from_ice_user(u));
- continue 'next_user;
+ match ice.lock() {
+ Ok(mut ice) => {
+ let users = match ice.get_users() {
+ Ok(user) => user,
+ Err(err) => return err.to_string().into_response(),
+ };
+ let mut channels = Vec::<Channel>::new();
+ 'next_user: for u in &users {
+ for c in &mut channels {
+ if c.path == u.channel_path {
+ c.users.push(User::from_ice_user(u));
+ continue 'next_user;
+ }
+ }
+ let channel = Channel {
+ path: u.channel_path.clone(),
+ positions: u.channel_path_positions.clone(),
+ users: vec![User::from_ice_user(u)],
+ };
+ channels.push(channel);
}
- }
- let channel = Channel {
- path: u.channel_path.clone(),
- positions: u.channel_path_positions.clone(),
- users: vec![User::from_ice_user(u)],
- };
- channels.push(channel);
- }
- for c in &mut channels {
- c.users.sort();
- }
+ for c in &mut channels {
+ c.users.sort();
+ }
- channels.sort();
+ channels.sort();
- MainTemplate { channels }
+ MainTemplate { channels }.into_response()
+ }
+ Err(err) => err.to_string().into_response(),
+ }
}
async fn shutdown_signal() {