diff options
| author | Fuwn <[email protected]> | 2021-05-28 00:06:40 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2021-05-28 00:06:40 -0700 |
| commit | 179ce3277ece536cae41b834469f4065e3600d82 (patch) | |
| tree | a96d55a34531c9761f6309c35f8d9cfab9879db6 | |
| parent | Merge branch 'develop' of https://github.com/Whirlsplash/whirl into develop (diff) | |
| download | whirl-179ce3277ece536cae41b834469f4065e3600d82.tar.xz whirl-179ce3277ece536cae41b834469f4065e3600d82.zip | |
fix(global): a lot of clippy warnings
This change makes clippy **a lot** more strict.
33 files changed, 260 insertions, 154 deletions
diff --git a/crates/whirl/src/cli.rs b/crates/whirl/src/cli.rs index c3fd198..54ce142 100644 --- a/crates/whirl/src/cli.rs +++ b/crates/whirl/src/cli.rs @@ -6,7 +6,10 @@ use whirl_config::Config; pub struct Cli; impl Cli { - pub async fn execute() -> Result<(), Box<dyn std::error::Error>> { + /// # Panics + /// Though Rust thinks a panic might happen because of the `unreachable` + /// macro, all CLI subcommands are handled so it is trully unreachable. + pub async fn execute() { let matches = Self::cli().get_matches(); if Config::get().whirlsplash.log.test { @@ -27,10 +30,11 @@ impl Cli { ("clean", _) => { let cleanable_directories = vec!["log/"]; for dir in cleanable_directories { - let mut file_type = "directory"; - if !dir.ends_with('/') { - file_type = "file"; - } + let file_type = if dir.ends_with('/') { + "directory" + } else { + "file" + }; info!("cleaning {}: {}", file_type, dir); if let Err(e) = std::fs::remove_dir_all(dir) { warn!("cannot delete {}: {}: {}", file_type, dir, e); @@ -39,8 +43,6 @@ impl Cli { } _ => unreachable!(), } - - Ok(()) } fn cli() -> App<'static, 'static> { diff --git a/crates/whirl/src/lib.rs b/crates/whirl/src/lib.rs index 47e0ecb..82a5a9f 100644 --- a/crates/whirl/src/lib.rs +++ b/crates/whirl/src/lib.rs @@ -8,7 +8,15 @@ decl_macro, proc_macro_hygiene )] -#![warn(rust_2018_idioms)] +#![deny( + warnings, + nonstandard_style, + unused, + future_incompatible, + rust_2018_idioms, + unsafe_code +)] +#![deny(clippy::all, clippy::nursery, clippy::pedantic)] #![recursion_limit = "128"] #[macro_use] @@ -30,6 +38,8 @@ use whirl_config::Config; pub struct Whirl; impl Whirl { + /// # Errors + /// - An error may arise if logger fails to start. pub async fn splash() -> Result<(), Box<dyn std::error::Error>> { // Environment std::env::set_var("DATABASE_URL", "whirl.sqlite3"); @@ -54,7 +64,7 @@ impl Whirl { } } - crate::cli::Cli::execute().await.unwrap(); + crate::cli::Cli::execute().await; Ok(()) } diff --git a/crates/whirl_api/Cargo.toml b/crates/whirl_api/Cargo.toml index 315b7ae..0ad7744 100644 --- a/crates/whirl_api/Cargo.toml +++ b/crates/whirl_api/Cargo.toml @@ -22,6 +22,7 @@ actix-cors = "0.5.4" sysinfo = "0.18.0" whirl_common = { path = "../whirl_common" } tokio = { version = "1.6.0", features = ["full"] } +num-traits = "0.2.14" # Serialization serde = "1.0.126" diff --git a/crates/whirl_api/src/lib.rs b/crates/whirl_api/src/lib.rs index d2f7811..e6660a7 100644 --- a/crates/whirl_api/src/lib.rs +++ b/crates/whirl_api/src/lib.rs @@ -10,7 +10,15 @@ decl_macro, proc_macro_hygiene )] -#![warn(rust_2018_idioms)] +#![deny( + warnings, + nonstandard_style, + unused, + future_incompatible, + rust_2018_idioms, + unsafe_code +)] +#![deny(clippy::all, clippy::nursery, clippy::pedantic)] #![recursion_limit = "128"] #[macro_use] @@ -25,6 +33,14 @@ mod routes; pub struct Api; impl Api { /// Begin handling connections on the web-server. + /// + /// # Errors + /// - An error may arise if the web-server is unable to bind the specified + /// port. + /// + /// # Panics + /// - A panic may occur if the mpsc sender is unable to send a clone of the + /// server. pub async fn listen( tx: std::sync::mpsc::Sender<actix_web::dev::Server>, address: &str, @@ -42,23 +58,28 @@ impl Api { info!("http api now listening at {}", address); - let _ = tx.send(server.clone()); + tx.send(server.clone()).unwrap(); sys.block_on(server) } } +/// # Panics +/// - A panic may occur if the mpsc sender is unable to send a clone of the +/// server. +#[must_use] pub fn make() -> tokio::task::JoinHandle<()> { // actix_web::rt::System::new("").block_on(rx.recv().unwrap().stop(true)); tokio::spawn(async move { - let _ = crate::Api::listen( + crate::Api::listen( std::sync::mpsc::channel().0, &*format!( "0.0.0.0:{}", whirl_config::Config::get().whirlsplash.api.port ), ) - .await; + .await + .unwrap(); }) } diff --git a/crates/whirl_api/src/routes/stats/mod.rs b/crates/whirl_api/src/routes/stats/mod.rs index 5a41630..02c3d22 100644 --- a/crates/whirl_api/src/routes/stats/mod.rs +++ b/crates/whirl_api/src/routes/stats/mod.rs @@ -3,7 +3,10 @@ pub mod structures; +use std::convert::TryFrom; + use actix_web::HttpResponse; +use num_traits::cast::AsPrimitive; use sysinfo::{get_current_pid, ProcessExt, System, SystemExt}; use crate::routes::stats::structures::{Statistics, StatisticsProcess, StatisticsSystem}; @@ -20,14 +23,14 @@ pub fn statistics() -> HttpResponse { system: StatisticsSystem { os_type: sys.get_name().unwrap(), release: sys.get_kernel_version().unwrap(), - uptime: whirl_common::system::seconds_to_hrtime( - sysinfo::System::new().get_uptime() as usize + uptime: whirl_common::system::seconds_to_hrtime( + usize::try_from(sysinfo::System::new().get_uptime()).unwrap(), ), }, process: StatisticsProcess { // (process.cpu_usage() * 100.0).round() / 100.0 memory_usage: (process.memory() / 1000).to_string(), - cpu_usage: (process.cpu_usage() / sys.get_processors().len() as f32).to_string(), + cpu_usage: (process.cpu_usage() / sys.get_processors().len().as_(): f32).to_string(), // uptime: seconds_to_hrtime((sys.get_uptime() - process.start_time()) as usize), }, }) diff --git a/crates/whirl_common/src/lib.rs b/crates/whirl_common/src/lib.rs index 081da1c..82eac48 100644 --- a/crates/whirl_common/src/lib.rs +++ b/crates/whirl_common/src/lib.rs @@ -10,7 +10,15 @@ decl_macro, proc_macro_hygiene )] -#![warn(rust_2018_idioms)] +#![deny( + warnings, + nonstandard_style, + unused, + future_incompatible, + rust_2018_idioms, + unsafe_code +)] +#![deny(clippy::all, clippy::nursery, clippy::pedantic)] #![recursion_limit = "128"] pub mod log; diff --git a/crates/whirl_common/src/log.rs b/crates/whirl_common/src/log.rs index e905bc8..d2df568 100644 --- a/crates/whirl_common/src/log.rs +++ b/crates/whirl_common/src/log.rs @@ -5,6 +5,7 @@ use whirl_config::Config; /// Grab the log level configuration key (`whirlsplash.log.level`) from the /// configuration file and evaluate the proper log level. +#[must_use] pub fn calculate_log_level() -> String { let mut level; diff --git a/crates/whirl_common/src/sort.rs b/crates/whirl_common/src/sort.rs index b1b79b2..7cbabd6 100644 --- a/crates/whirl_common/src/sort.rs +++ b/crates/whirl_common/src/sort.rs @@ -3,6 +3,6 @@ /// Sort a vector by alphabetical order based on the first character of each /// string. -pub fn sort_vec_alphabetically(vec: &mut Vec<&str>) { +pub fn vec_alphabetically(vec: &mut Vec<&str>) { vec.sort_by(|a, b| a.to_lowercase().cmp(&b.to_lowercase())); } diff --git a/crates/whirl_common/src/system.rs b/crates/whirl_common/src/system.rs index 3b4806b..2fb79e7 100644 --- a/crates/whirl_common/src/system.rs +++ b/crates/whirl_common/src/system.rs @@ -17,6 +17,7 @@ fn make_parts(t: usize, steps: &[usize], mut accum: Vec<usize>) -> Vec<usize> { } /// Convert a Unix (Epoch) Timestamp to a human-readable format. +#[must_use] pub fn seconds_to_hrtime(seconds: usize) -> String { let word = ["week", "day", "hour", "min", "sec"]; diff --git a/crates/whirl_config/src/lib.rs b/crates/whirl_config/src/lib.rs index 63fd5d0..e7bc121 100644 --- a/crates/whirl_config/src/lib.rs +++ b/crates/whirl_config/src/lib.rs @@ -10,7 +10,15 @@ decl_macro, proc_macro_hygiene )] -#![warn(rust_2018_idioms)] +#![deny( + warnings, + nonstandard_style, + unused, + future_incompatible, + rust_2018_idioms, + unsafe_code +)] +#![deny(clippy::all, clippy::nursery, clippy::pedantic)] #![recursion_limit = "128"] #[macro_use] @@ -39,11 +47,14 @@ pub struct Config { } impl Config { /// Re-fetch the configuration from the configuration file. + /// + /// # Panics + /// - May panic if the configuration is unable to be refreshed. #[deprecated( note = "the current implementation of the configurations system automatically performs \ refreshes, this method has no effects" )] - pub fn refresh() { let _ = config::Config::new().refresh(); } + pub fn refresh() { let _ = config::Config::new().refresh().unwrap(); } fn load() -> Result<Self, ConfigError> { let mut s = config::Config::new(); @@ -53,7 +64,11 @@ impl Config { } /// Get a certain configuration key or group from the configuration file. - pub fn get() -> Config { + /// + /// # Panics + /// - May panic if the configuration is unable to be read. + #[must_use] + pub fn get() -> Self { return if let Err(why) = Self::load() { error!( "unable to load configuration file, reverting to default value: {}", @@ -67,7 +82,7 @@ impl Config { } impl Default for Config { fn default() -> Self { - Config { + Self { whirlsplash: WhirlsplashConfig { worldsmaster_username: "WORLDSMASTER".to_string(), ip: "0.0.0.0".to_string(), diff --git a/crates/whirl_config/src/structures.rs b/crates/whirl_config/src/structures.rs index 4f1d62e..5b2f163 100644 --- a/crates/whirl_config/src/structures.rs +++ b/crates/whirl_config/src/structures.rs @@ -18,6 +18,7 @@ pub struct WhirlsplashPromptConfig { pub enable: bool, pub ps1: String, } +#[allow(clippy::struct_excessive_bools)] #[derive(Serialize, Deserialize, Debug)] pub struct WhirlsplashLogConfig { pub enable: bool, diff --git a/crates/whirl_db/src/lib.rs b/crates/whirl_db/src/lib.rs index eda95bf..399e186 100644 --- a/crates/whirl_db/src/lib.rs +++ b/crates/whirl_db/src/lib.rs @@ -10,7 +10,15 @@ decl_macro, proc_macro_hygiene )] -#![warn(rust_2018_idioms)] +#![deny( + warnings, + nonstandard_style, + unused, + future_incompatible, + rust_2018_idioms, + unsafe_code +)] +#![deny(clippy::all, clippy::nursery, clippy::pedantic)] #![recursion_limit = "128"] #[macro_use] @@ -23,7 +31,11 @@ use diesel::prelude::*; // use crate::db::models::*; -/// Establish a connection to the SQLite database. +/// Establish a connection to the `SQLite` database. +/// +/// # Panics +/// - May panic if the database URL is inaccessible. +#[must_use] pub fn establish_connection() -> SqliteConnection { let database_url = std::env::var("DATABASE_URL").unwrap_or_else(|_| "whirl.sqlite3".to_string()); SqliteConnection::establish(&database_url) diff --git a/crates/whirl_prompt/src/builtins/mod.rs b/crates/whirl_prompt/src/builtins/mod.rs index 62031de..2bebd31 100644 --- a/crates/whirl_prompt/src/builtins/mod.rs +++ b/crates/whirl_prompt/src/builtins/mod.rs @@ -23,7 +23,7 @@ pub fn builtin_history(history: &[String]) -> i32 { } pub fn builtin_help() -> i32 { - for help in HELPABLES_BUILTINS.iter() { + for help in &HELPABLES_BUILTINS { println!("{}", help); } @@ -80,7 +80,7 @@ pub fn builtin_config(args: &[String]) -> i32 { match sub.as_str() { "show" => println!("{:#?}", Config::get()), "help" | "--help" | "-h" => - for help in HELPABLES_BUILTIN_CONFIG.iter() { + for help in &HELPABLES_BUILTIN_CONFIG { println!("{}", help); }, // "refresh" => Config::refresh(), diff --git a/crates/whirl_prompt/src/builtins/structures.rs b/crates/whirl_prompt/src/builtins/structures.rs index 4217a38..59df31b 100644 --- a/crates/whirl_prompt/src/builtins/structures.rs +++ b/crates/whirl_prompt/src/builtins/structures.rs @@ -19,15 +19,15 @@ impl FromStr for BuiltIn { fn from_str(s: &str) -> Result<Self, Self::Err> { match s { - "echo" => Ok(BuiltIn::Echo), - "history" => Ok(BuiltIn::History), - "exit" => Ok(BuiltIn::Exit), - "null" => Ok(BuiltIn::Null), - "help" => Ok(BuiltIn::Help), - "ls" => Ok(BuiltIn::Ls), - "cat" => Ok(BuiltIn::Cat), - "config" => Ok(BuiltIn::Config), - "fetch" => Ok(BuiltIn::Fetch), + "echo" => Ok(Self::Echo), + "history" => Ok(Self::History), + "exit" => Ok(Self::Exit), + "null" => Ok(Self::Null), + "help" => Ok(Self::Help), + "ls" => Ok(Self::Ls), + "cat" => Ok(Self::Cat), + "config" => Ok(Self::Config), + "fetch" => Ok(Self::Fetch), _ => Err(()), } } diff --git a/crates/whirl_prompt/src/lib.rs b/crates/whirl_prompt/src/lib.rs index e33adce..a7b2389 100644 --- a/crates/whirl_prompt/src/lib.rs +++ b/crates/whirl_prompt/src/lib.rs @@ -10,7 +10,15 @@ decl_macro, proc_macro_hygiene )] -#![warn(rust_2018_idioms)] +#![deny( + warnings, + nonstandard_style, + unused, + future_incompatible, + rust_2018_idioms, + unsafe_code +)] +#![deny(clippy::all, clippy::nursery, clippy::pedantic)] #![recursion_limit = "128"] mod builtins; @@ -40,15 +48,15 @@ pub struct Prompt { impl Prompt { /// Begin handling user input as the prompt. pub async fn handle() -> ! { - let mut prompt = Prompt { + let mut prompt = Self { history: vec![] }; loop { - Prompt::write_prompt(); - let command = prompt.read_command(); + Self::write_prompt(); + let command = Self::read_command(); prompt - .process_command(Prompt::tokenize_command(command)) + .process_command(Self::tokenize_command(&command)) .await; } } @@ -58,7 +66,7 @@ impl Prompt { io::stdout().flush().unwrap(); } - fn read_command(&mut self) -> String { + fn read_command() -> String { let mut input = String::new(); io::stdin() .read_line(&mut input) @@ -71,8 +79,11 @@ impl Prompt { input } - fn tokenize_command(c: String) -> Command { - let mut command_split: Vec<String> = c.split_whitespace().map(|s| s.to_string()).collect(); + fn tokenize_command(c: &str) -> Command { + let mut command_split: Vec<String> = c + .split_whitespace() + .map(std::string::ToString::to_string) + .collect(); Command { keyword: command_split.remove(0), @@ -113,38 +124,26 @@ mod tokenize_command { #[test] #[ignore] - fn empty_command() { assert_eq!("", Prompt::tokenize_command("".to_string()).keyword) } + fn empty_command() { assert_eq!("", Prompt::tokenize_command("").keyword) } #[test] - fn test_keyword() { assert_eq!("test", Prompt::tokenize_command("test".to_string()).keyword) } + fn test_keyword() { assert_eq!("test", Prompt::tokenize_command("test").keyword) } #[test] - fn no_arg() { assert_eq!(0, Prompt::tokenize_command("test".to_string()).args.len()) } + fn no_arg() { assert_eq!(0, Prompt::tokenize_command("test").args.len()) } #[test] - fn one_arg() { - assert_eq!( - 1, - Prompt::tokenize_command("test one".to_string()).args.len() - ) - } + fn one_arg() { assert_eq!(1, Prompt::tokenize_command("test one").args.len()) } #[test] - fn multi_arg() { - assert_eq!( - 3, - Prompt::tokenize_command("test one two three".to_string()) - .args - .len() - ) - } + fn multi_arg() { assert_eq!(3, Prompt::tokenize_command("test one two three").args.len()) } #[test] #[ignore] fn quotes() { assert_eq!( 2, - Prompt::tokenize_command("test \"one two\" three".to_string()) + Prompt::tokenize_command("test \"one two\" three") .args .len() ) diff --git a/crates/whirl_server/Cargo.toml b/crates/whirl_server/Cargo.toml index 4aeb4b0..f18f355 100644 --- a/crates/whirl_server/Cargo.toml +++ b/crates/whirl_server/Cargo.toml @@ -19,6 +19,7 @@ log = "0.4.14" # Utility async-trait = "0.1.50" +num-traits = "0.2.14" # Byte Manipulation bytes = "1.0.1" diff --git a/crates/whirl_server/src/cmd/commands/action.rs b/crates/whirl_server/src/cmd/commands/action.rs index 8d1fb0b..4ba7065 100644 --- a/crates/whirl_server/src/cmd/commands/action.rs +++ b/crates/whirl_server/src/cmd/commands/action.rs @@ -8,8 +8,9 @@ // of actions, it will be of2m-ified. use bytes::{BufMut, BytesMut}; +use num_traits::AsPrimitive; -pub fn create_action() -> Vec<u8> { +pub fn create() -> Vec<u8> { let mut command = BytesMut::new(); command.put_slice(&[ @@ -19,7 +20,7 @@ pub fn create_action() -> Vec<u8> { // Convert to vector and insert the length let mut command_as_vec = command.to_vec(); - command_as_vec.insert(0, command.len() as u8 + 1); + command_as_vec.insert(0, command.len().as_(): u8 + 1); // Return bytes command_as_vec diff --git a/crates/whirl_server/src/cmd/commands/buddy_list.rs b/crates/whirl_server/src/cmd/commands/buddy_list.rs index 9757519..f80c86d 100644 --- a/crates/whirl_server/src/cmd/commands/buddy_list.rs +++ b/crates/whirl_server/src/cmd/commands/buddy_list.rs @@ -4,6 +4,7 @@ use std::str::from_utf8; use bytes::{BufMut, BytesMut}; +use num_traits::AsPrimitive; use crate::cmd::{ constants::BUDDYLISTNOTIFY, @@ -22,7 +23,7 @@ impl Parsable for BuddyList { .to_string(), // Get the last byte - add: data[data[0] as usize - 1] as i8, + add: data[data[0] as usize - 1].as_(): i8, } } } @@ -32,15 +33,15 @@ impl Creatable for BuddyList { // Header command.put_u8(0x01); // ObjId - command.put_i8(BUDDYLISTNOTIFY as i8); // Type + command.put_i8(BUDDYLISTNOTIFY.as_(): i8); // Type // Content - command.put_u8(self.buddy.len() as u8); // Buddy (name) length + command.put_u8(self.buddy.len().as_(): u8); // Buddy (name) length command.put_slice(self.buddy.as_bytes()); // Buddy (name) - command.put_u8(self.add as u8); // "Is buddy logged on?" (?) + command.put_u8(self.add.as_(): u8); // "Is buddy logged on?" (?) let mut command_as_vec = command.to_vec(); - command_as_vec.insert(0, command.len() as u8 + 1); + command_as_vec.insert(0, command.len().as_(): u8 + 1); command_as_vec } diff --git a/crates/whirl_server/src/cmd/commands/property/create.rs b/crates/whirl_server/src/cmd/commands/property/create.rs index 40ec2be..94cf75b 100644 --- a/crates/whirl_server/src/cmd/commands/property/create.rs +++ b/crates/whirl_server/src/cmd/commands/property/create.rs @@ -27,7 +27,7 @@ use crate::{ }, }; -pub fn create_property_update_as_distributor() -> Vec<u8> { +pub fn property_update_as_distributor() -> Vec<u8> { property_list_to_bytes( PROPUPD, 0xFF, @@ -64,7 +64,7 @@ pub fn create_property_update_as_distributor() -> Vec<u8> { ) } -pub fn create_property_update_as_hub() -> Vec<u8> { +pub fn property_update_as_hub() -> Vec<u8> { property_list_to_bytes( PROPUPD, 0xFF, @@ -105,7 +105,7 @@ pub fn create_property_update_as_hub() -> Vec<u8> { ) } -pub fn create_property_request_as_distributor() -> Vec<u8> { +pub fn property_request_as_distributor() -> Vec<u8> { property_list_to_bytes( SESSINIT as i32, 0x01, @@ -142,7 +142,7 @@ pub fn create_property_request_as_distributor() -> Vec<u8> { ) } -pub fn create_property_request_as_hub() -> Vec<u8> { +pub fn property_request_as_hub() -> Vec<u8> { property_list_to_bytes( SESSINIT as i32, 0x01, diff --git a/crates/whirl_server/src/cmd/commands/redirect_id.rs b/crates/whirl_server/src/cmd/commands/redirect_id.rs index 942c06d..9727107 100644 --- a/crates/whirl_server/src/cmd/commands/redirect_id.rs +++ b/crates/whirl_server/src/cmd/commands/redirect_id.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use bytes::{BufMut, BytesMut}; +use num_traits::AsPrimitive; use whirl_config::Config; use crate::cmd::{constants::REDIRID, extendable::Creatable}; @@ -17,24 +18,24 @@ impl Creatable for RedirectId { // Header command.put_u8(0x01); // ObjId - command.put_u8(REDIRID as u8); // Type + command.put_u8(REDIRID.as_(): u8); // Type // Content - command.put_u8(self.room_name.len() as u8); // Room name length + command.put_u8(self.room_name.len().as_(): u8); // Room name length command.put_slice(self.room_name.as_bytes()); // Room name // command.put_u8(0x00); // Unimplemented byte (?) // command.put_u8(room_id); // Room ID - command.put_u16(self.room_number as u16); // Room ID + command.put_u16(self.room_number.as_(): u16); // Room ID // IP for byte in Config::get().whirlsplash.ip.split('.') { command.put_u8(byte.parse::<u8>().unwrap()); } - command.put_u16(Config::get().hub.port as u16); // Port + command.put_u16(Config::get().hub.port.as_(): u16); // Port // Length let mut command_as_vec = command.to_vec(); - command_as_vec.insert(0, command.len() as u8 + 1); + command_as_vec.insert(0, command.len().as_(): u8 + 1); // Return command_as_vec diff --git a/crates/whirl_server/src/cmd/commands/subscribe_room.rs b/crates/whirl_server/src/cmd/commands/subscribe_room.rs index 9e7d732..8ed4876 100644 --- a/crates/whirl_server/src/cmd/commands/subscribe_room.rs +++ b/crates/whirl_server/src/cmd/commands/subscribe_room.rs @@ -3,6 +3,7 @@ use byteorder::{BigEndian, ReadBytesExt}; use bytes::{Buf, BytesMut}; +use num_traits::AsPrimitive; use crate::cmd::extendable::Parsable; @@ -20,11 +21,11 @@ impl Parsable for SubscribeRoom { let mut data = BytesMut::from(data.as_slice()).reader(); Self { - room_number: data.read_i16::<BigEndian>().unwrap() as i8, - x: data.read_i16::<BigEndian>().unwrap() as i8 as f32, - y: data.read_i16::<BigEndian>().unwrap() as i8 as f32, - z: data.read_i16::<BigEndian>().unwrap() as i8 as f32, - distance: data.read_i16::<BigEndian>().unwrap() as i8 as f32, // + 100 + room_number: data.read_i16::<BigEndian>().unwrap().as_(): i8, + x: f32::from(data.read_i16::<BigEndian>().unwrap().as_(): i8), + y: f32::from(data.read_i16::<BigEndian>().unwrap().as_(): i8), + z: f32::from(data.read_i16::<BigEndian>().unwrap().as_(): i8), + distance: f32::from(data.read_i16::<BigEndian>().unwrap().as_(): i8), // + 100 } } } diff --git a/crates/whirl_server/src/cmd/commands/teleport.rs b/crates/whirl_server/src/cmd/commands/teleport.rs index ef8f6b2..39c78f9 100644 --- a/crates/whirl_server/src/cmd/commands/teleport.rs +++ b/crates/whirl_server/src/cmd/commands/teleport.rs @@ -3,6 +3,7 @@ use byteorder::{BigEndian, ReadBytesExt}; use bytes::{Buf, BytesMut}; +use num_traits::AsPrimitive; use crate::cmd::extendable::Parsable; @@ -22,13 +23,13 @@ impl Parsable for Teleport { let mut data = BytesMut::from(data.as_slice()).reader(); Self { - room_id: data.read_u16::<BigEndian>().unwrap() as i8, + room_id: data.read_u16::<BigEndian>().unwrap().as_(): i8, exit_type: data.read_u8().unwrap(), entry_type: data.read_u8().unwrap(), - x: data.read_i16::<BigEndian>().unwrap() as f32, - y: data.read_i16::<BigEndian>().unwrap() as f32, - z: data.read_i16::<BigEndian>().unwrap() as f32, - direction: data.read_i16::<BigEndian>().unwrap() as f32, + x: f32::from(data.read_i16::<BigEndian>().unwrap()), + y: f32::from(data.read_i16::<BigEndian>().unwrap()), + z: f32::from(data.read_i16::<BigEndian>().unwrap()), + direction: f32::from(data.read_i16::<BigEndian>().unwrap()), } } } diff --git a/crates/whirl_server/src/cmd/commands/text.rs b/crates/whirl_server/src/cmd/commands/text.rs index 9f3fb00..414dc64 100644 --- a/crates/whirl_server/src/cmd/commands/text.rs +++ b/crates/whirl_server/src/cmd/commands/text.rs @@ -4,6 +4,7 @@ use std::str::from_utf8; use bytes::{BufMut, BytesMut}; +use num_traits::AsPrimitive; use crate::cmd::{ constants::TEXT, @@ -20,7 +21,7 @@ impl Creatable for Text { // Header command.put_u8(0x01); - command.put_i8(TEXT as i8); + command.put_i8(TEXT.as_(): i8); // Content // TODO: Find a way to parse ObjIds. @@ -28,14 +29,14 @@ impl Creatable for Text { // The below byte is suspected to be the sender's short ObjId. command.put_i8(0x00); - command.put_u8(self.sender.len() as u8); + command.put_u8(self.sender.len().as_(): u8); command.put_slice(self.sender.as_bytes()); - command.put_u8(self.content.len() as u8); + command.put_u8(self.content.len().as_(): u8); command.put_slice(self.content.as_bytes()); // Convert to vector and insert the length let mut command_as_vec = command.to_vec(); - command_as_vec.insert(0, command.len() as u8 + 1); + command_as_vec.insert(0, command.len().as_(): u8 + 1); // Return bytes command_as_vec diff --git a/crates/whirl_server/src/cmd/set_parser.rs b/crates/whirl_server/src/cmd/set_parser.rs index 600badd..5aa5b21 100644 --- a/crates/whirl_server/src/cmd/set_parser.rs +++ b/crates/whirl_server/src/cmd/set_parser.rs @@ -20,9 +20,9 @@ fn _parse_command_set(mut data: Vec<u8>) -> Vec<Command> { let command_length = data[0]; let mut command = Command { - length: command_length as i32, - obj_id: data[1] as i32, - id: data[2] as i32, + length: i32::from(command_length), + obj_id: i32::from(data[1]), + id: i32::from(data[2]), body: vec![], }; if command.length > 3 { diff --git a/crates/whirl_server/src/cmd/structure.rs b/crates/whirl_server/src/cmd/structure.rs index 23e91ca..a9f6ceb 100644 --- a/crates/whirl_server/src/cmd/structure.rs +++ b/crates/whirl_server/src/cmd/structure.rs @@ -8,11 +8,11 @@ pub struct Command { pub body: Vec<u8>, } impl Command { - pub fn _new() -> Self { Command::default() } + pub fn _new() -> Self { Self::default() } } impl Default for Command { fn default() -> Self { - Command { + Self { length: 0, obj_id: 0, id: 0, diff --git a/crates/whirl_server/src/distributor.rs b/crates/whirl_server/src/distributor.rs index a22316e..de87dcd 100644 --- a/crates/whirl_server/src/distributor.rs +++ b/crates/whirl_server/src/distributor.rs @@ -2,17 +2,18 @@ // SPDX-License-Identifier: GPL-3.0-only //! The Distributor functions as bare-minimal -//! [AutoServer](http://dev.worlds.net/private/GammaDocs/WorldServer.html#AutoServer). +//! [`AutoServer`](http://dev.worlds.net/private/GammaDocs/WorldServer.html#AutoServer). //! -//! The Distributor intercepts a client on initial connection and distributes it -//! to a -//! [RoomServer](http://dev.worlds.net/private/GammaDocs/WorldServer.html#RoomServer). +//! The Distributor intercepts a client on initial connection and distributes +//! it to a +//! [`RoomServer`](http://dev.worlds.net/private/GammaDocs/WorldServer.html#RoomServer). //! -//! This is not meant to be a high focus module as the Distributor is only meant -//! to handle the initial and brief session initialization of the client. +//! This is not meant to be a high focus module as the Distributor is only +//! meant to handle the initial and brief session initialization of the client. use std::{error::Error, net::SocketAddr, sync::Arc}; +use num_traits::cast::AsPrimitive; use tokio::{io::AsyncWriteExt, net::TcpStream, sync::Mutex}; use tokio_stream::StreamExt; use tokio_util::codec::{BytesCodec, Decoder}; @@ -21,17 +22,17 @@ use whirl_config::Config; use crate::{ cmd::{ commands::{ - action::create_action, + action::create, buddy_list::BuddyList, property::{ - create::{create_property_request_as_distributor, create_property_update_as_distributor}, + create::{property_request_as_distributor, property_update_as_distributor}, parse::find_property_in_property_list, }, redirect_id::RedirectId, room_id_request::RoomIdRequest, text::Text, }, - constants::*, + constants::{BUDDYLISTUPDATE, PROPREQ, PROPSET, ROOMIDRQ, SESSEXIT, SESSINIT}, extendable::{Creatable, Parsable}, }, interaction::{peer::Peer, shared::Shared}, @@ -63,12 +64,12 @@ impl Server for Distributor { result = peer.bytes.next() => match result { Some(Ok(msg)) => { for msg in parse_commands_from_packet(msg) { - match msg.get(2).unwrap().to_owned() as i32 { + match msg.get(2).unwrap().to_owned().as_(): i32 { PROPREQ => { debug!("received property request from client"); peer.bytes.get_mut() - .write_all(&create_property_update_as_distributor()).await?; + .write_all(&property_update_as_distributor()).await?; trace!("sent property update to client"); } SESSINIT => { @@ -80,7 +81,7 @@ impl Server for Distributor { debug!("received session initialization from {}", username); peer.bytes.get_mut() - .write_all(&create_property_request_as_distributor()).await?; + .write_all(&property_request_as_distributor()).await?; trace!("sent property request to {}", username); } PROPSET => { @@ -92,7 +93,7 @@ impl Server for Distributor { content: Config::get().distributor.worldsmaster_greeting, }.create()).await?; peer.bytes.get_mut() - .write_all(&create_action()).await?; + .write_all(&create()).await?; trace!("sent text to {}", username); } BUDDYLISTUPDATE => { @@ -106,19 +107,19 @@ impl Server for Distributor { debug!("received room id request from {}: {}", username, &room.room_name); let room_id; - if !room_ids.contains(&room.room_name) { - room_ids.push((&*room.room_name).to_string()); - room_id = room_ids.iter().position(|r| r == &room.room_name).unwrap(); - trace!("inserted room: {}", room.room_name); - } else { + if room_ids.contains(&room.room_name) { let position = room_ids.iter().position(|r| r == &room.room_name).unwrap(); trace!("found room: {}", room.room_name); room_id = position; + } else { + room_ids.push((&*room.room_name).to_string()); + room_id = room_ids.iter().position(|r| r == &room.room_name).unwrap(); + trace!("inserted room: {}", room.room_name); } peer.bytes.get_mut().write_all(&RedirectId { room_name: (&*room.room_name).to_string(), - room_number: room_id as i8, + room_number: room_id.as_(): i8, }.create()).await?; trace!("sent redirect id to {}: {}", username, room.room_name); } diff --git a/crates/whirl_server/src/hub.rs b/crates/whirl_server/src/hub.rs index 55c23eb..b2e2dfb 100644 --- a/crates/whirl_server/src/hub.rs +++ b/crates/whirl_server/src/hub.rs @@ -2,14 +2,15 @@ // SPDX-License-Identifier: GPL-3.0-only //! The Hub functions as a -//! [RoomServer](http://dev.worlds.net/private/GammaDocs/WorldServer.html#AutoServer). +//! [`RoomServer`](http://dev.worlds.net/private/GammaDocs/WorldServer.html#AutoServer). //! -//! A RoomServer is responsible for handling just about every request from the +//! A `RoomServer` is responsible for handling just about every request from the //! client after they have been redirected to a room (Hub) and finished their -//! business with the Distributor (AutoServer). +//! business with the Distributor (`AutoServer`). use std::{error::Error, net::SocketAddr, sync::Arc}; +use num_traits::cast::AsPrimitive; use tokio::{io::AsyncWriteExt, net::TcpStream, sync::Mutex}; use tokio_stream::StreamExt; use tokio_util::codec::{BytesCodec, Decoder}; @@ -18,10 +19,10 @@ use whirl_config::Config; use crate::{ cmd::{ commands::{ - action::create_action, + action::create, buddy_list::BuddyList, property::{ - create::{create_property_request_as_hub, create_property_update_as_hub}, + create::{property_request_as_hub, property_update_as_hub}, parse::find_property_in_property_list, }, subscribe_distance::SubscribeDistance, @@ -29,7 +30,17 @@ use crate::{ teleport::Teleport, text::Text, }, - constants::*, + constants::{ + BUDDYLISTUPDATE, + PROPREQ, + PROPSET, + SESSEXIT, + SESSINIT, + SUBSCRIB, + SUB_DIST, + TELEPORT, + TEXT, + }, extendable::{Creatable, Parsable, ParsableWithArguments}, }, interaction::{peer::Peer, shared::Shared}, @@ -63,12 +74,12 @@ impl Server for Hub { Some(Ok(msg)) => { // trace!("got some bytes: {:?}", &msg); for msg in parse_commands_from_packet(msg) { - match msg.get(2).unwrap().to_owned() as i32 { + match msg.get(2).unwrap().to_owned().as_(): i32 { PROPREQ => { debug!("received property request from client"); peer.bytes.get_mut() - .write_all(&create_property_update_as_hub()).await?; + .write_all(&property_update_as_hub()).await?; trace!("sent property update to client"); } SESSINIT => { @@ -80,7 +91,7 @@ impl Server for Hub { debug!("received session initialization from {}", username); peer.bytes.get_mut() - .write_all(&create_property_request_as_hub()).await?; + .write_all(&property_request_as_hub()).await?; trace!("sent property request to {}", username); } PROPSET => { @@ -92,7 +103,7 @@ impl Server for Hub { content: Config::get().distributor.worldsmaster_greeting, }.create()).await?; peer.bytes.get_mut() - .write_all(&create_action()).await?; + .write_all(&create()).await?; trace!("sent text to {}", username); } BUDDYLISTUPDATE => { diff --git a/crates/whirl_server/src/interaction/peer.rs b/crates/whirl_server/src/interaction/peer.rs index 38c02c5..6a04b17 100644 --- a/crates/whirl_server/src/interaction/peer.rs +++ b/crates/whirl_server/src/interaction/peer.rs @@ -20,11 +20,11 @@ impl Peer { state: Arc<Mutex<Shared>>, bytes: Framed<TcpStream, BytesCodec>, username: String, - ) -> std::io::Result<Peer> { + ) -> std::io::Result<Self> { let (tx, rx) = mpsc::unbounded_channel(); state.lock().await.peers.insert(username, tx); - Ok(Peer { + Ok(Self { bytes, rx, }) diff --git a/crates/whirl_server/src/interaction/shared.rs b/crates/whirl_server/src/interaction/shared.rs index c2ee671..7ad2510 100644 --- a/crates/whirl_server/src/interaction/shared.rs +++ b/crates/whirl_server/src/interaction/shared.rs @@ -12,13 +12,13 @@ pub struct Shared { } impl Shared { pub fn new() -> Self { - Shared { + Self { peers: HashMap::new(), } } pub async fn broadcast(&mut self, message: &[u8]) { - for peer in self.peers.iter_mut() { + for peer in &mut self.peers { peer.1.send(BytesMut::from(message)).unwrap(); } } diff --git a/crates/whirl_server/src/lib.rs b/crates/whirl_server/src/lib.rs index 1a00c61..c1ff7e8 100644 --- a/crates/whirl_server/src/lib.rs +++ b/crates/whirl_server/src/lib.rs @@ -10,7 +10,15 @@ decl_macro, proc_macro_hygiene )] -#![warn(rust_2018_idioms)] +#![deny( + warnings, + nonstandard_style, + unused, + future_incompatible, + rust_2018_idioms, + unsafe_code +)] +#![deny(clippy::all, clippy::nursery, clippy::pedantic)] // clippy::pedantic #![recursion_limit = "128"] #[macro_use] @@ -35,22 +43,17 @@ use tokio::{ }; use whirl_config::Config; -use crate::{ - distributor::Distributor, - hub::Hub, - interaction::shared::Shared, - ServerType::{AutoServer, RoomServer}, -}; +use crate::interaction::shared::Shared; /// The type of server the `listen` method of the `Server` trait will /// implemented for. #[derive(Debug)] pub enum ServerType { - AnonRoomServer, - AnonUserServer, - AutoServer, - RoomServer, - UserServer, + AnonRoom, + AnonUser, + Auto, + Room, + User, } // https://stackoverflow.com/a/32712140/14452787 impl fmt::Display for ServerType { @@ -99,17 +102,26 @@ pub trait Server { ) -> Result<(), Box<dyn Error>>; } +/// # Panics +/// - A panic may occur if the TCP server is unable to bind the specified port. +#[must_use] pub fn make() -> Vec<tokio::task::JoinHandle<()>> { vec![ tokio::spawn(async move { - let _ = Distributor::listen( + crate::distributor::Distributor::listen( &*format!("0.0.0.0:{}", Config::get().distributor.port), - AutoServer, + ServerType::Auto, ) - .await; + .await + .unwrap(); }), tokio::spawn(async move { - let _ = Hub::listen(&*format!("0.0.0.0:{}", Config::get().hub.port), RoomServer).await; + crate::hub::Hub::listen( + &*format!("0.0.0.0:{}", Config::get().hub.port), + ServerType::Room, + ) + .await + .unwrap(); }), ] } diff --git a/crates/whirl_server/src/net/converter.rs b/crates/whirl_server/src/net/converter.rs index c976dff..d337d1a 100644 --- a/crates/whirl_server/src/net/converter.rs +++ b/crates/whirl_server/src/net/converter.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use bytes::{BufMut, BytesMut}; +use num_traits::AsPrimitive; use crate::{ cmd::constants::PROPUPD, @@ -29,15 +30,15 @@ pub fn property_list_to_bytes( let property = &property_list[0]; // Property we are currently iterating over trace!("current prop: {}:{}", property.prop_id, property.value); - command.put_u8(property.prop_id as u8); // Property ID + command.put_u8(property.prop_id.as_(): u8); // Property ID // NOTE: THIS IS SUPER BAD DO NOT DO THIS! But it works! if command_id == PROPUPD { - command.put_u8(PROPFLAG_DBSTORE as u8); // Flag (s) - command.put_u8(PROPACCESS_POSSESS as u8); // Access + command.put_u8(PROPFLAG_DBSTORE.as_(): u8); // Flag (s) + command.put_u8(PROPACCESS_POSSESS.as_(): u8); // Access } - command.put_u8(property.value.len() as u8); // Property UTF-8 Length + command.put_u8(property.value.len().as_(): u8); // Property UTF-8 Length command.put_slice(property.value.as_bytes()); // Property UTF-8 property_list.reverse(); @@ -48,9 +49,9 @@ pub fn property_list_to_bytes( // Convert to vector and insert the header let mut command_as_vec = command.to_vec(); - command_as_vec.insert(0, command_id as u8); // Command ID - command_as_vec.insert(0, obj_id as u8); // ObjId - command_as_vec.insert(0, command.len() as u8 + 3); // Data length + command_as_vec.insert(0, command_id.as_(): u8); // Command ID + command_as_vec.insert(0, obj_id.as_(): u8); // ObjId + command_as_vec.insert(0, command.len().as_(): u8 + 3); // Data length // Return bytes command_as_vec diff --git a/crates/whirl_server/src/net/property_parser.rs b/crates/whirl_server/src/net/property_parser.rs index bce457d..ac363d2 100644 --- a/crates/whirl_server/src/net/property_parser.rs +++ b/crates/whirl_server/src/net/property_parser.rs @@ -23,7 +23,7 @@ pub fn parse_network_property(mut data: Vec<u8>) -> Vec<NetworkProperty> { let property_length = data[1] + 2; property_list.push(NetworkProperty { - prop_id: data[0] as i32, + prop_id: i32::from(data[0]), value: from_utf8(&data[2..data[1] as usize + 2]) .unwrap() .to_string(), diff --git a/crates/whirl_server/src/net/structure.rs b/crates/whirl_server/src/net/structure.rs index 8c9d137..1549340 100644 --- a/crates/whirl_server/src/net/structure.rs +++ b/crates/whirl_server/src/net/structure.rs @@ -10,7 +10,7 @@ pub struct NetworkProperty { // } impl Default for NetworkProperty { fn default() -> Self { - NetworkProperty { + Self { prop_id: 0, value: "".to_string(), } |