diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9bad2bc8..f5bff809 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,7 +59,8 @@ jobs: cargo clippy --package maa-cli -- -D warnings - name: Lint (rustfmt) run: | - cargo fmt --package maa-cli -- --check + rustup toolchain install nightly -c rustfmt + cargo +nightly fmt --package maa-cli -- --check - name: Install MaaCore env: MAA_CONFIG_DIR: ${{ github.workspace }}/maa-cli/config_examples @@ -154,7 +155,9 @@ jobs: - name: Lint (clippy) run: cargo clippy --package maa-sys -- -D warnings - name: Lint (fmt) - run: cargo fmt --package maa-sys -- --check + run: | + rustup toolchain install nightly -c rustfmt + cargo +nightly fmt --package maa-sys -- --check - name: Test # It seems rust needs a static library to check the linking. # Without this, we can not link maa-sys to MaaCore on Windows. diff --git a/maa-cli/src/activity.rs b/maa-cli/src/activity.rs index 4f78526b..a5fbc853 100644 --- a/maa-cli/src/activity.rs +++ b/maa-cli/src/activity.rs @@ -1,5 +1,3 @@ -use crate::{config::task::ClientType, dirs}; - use std::{io::Write, path::Path, sync::OnceLock}; use anyhow::{bail, Context, Result}; @@ -8,6 +6,8 @@ use log::warn; use serde::Deserialize; use serde_json::Value as JsonValue; +use crate::{config::task::ClientType, dirs}; + fn stage_activity() -> Option<&'static StageActivityJson> { static STAGE_ACTIVITY: OnceLock> = OnceLock::new(); @@ -210,10 +210,10 @@ impl WarnError for std::result::Result { #[cfg(test)] mod tests { - use super::*; - use std::env::var_os; + use super::*; + #[test] fn parse_time_from_activity_info() { use chrono::{TimeZone, Utc}; diff --git a/maa-cli/src/cleanup.rs b/maa-cli/src/cleanup.rs index bb423211..c01677e2 100644 --- a/maa-cli/src/cleanup.rs +++ b/maa-cli/src/cleanup.rs @@ -1,8 +1,3 @@ -use crate::{ - dirs::{cache, log, state}, - value::userinput::{BoolInput, UserInput}, -}; - use std::{ borrow::Cow, fs::{read_dir, DirEntry}, @@ -12,14 +7,19 @@ use std::{ use anyhow::{bail, Result}; +use crate::{ + dirs::{cache, log, state}, + value::userinput::{BoolInput, UserInput}, +}; + pub trait PathProvider { /// Path to a directory to be cleaned up fn target_dir(&self) -> Cow; /// Determine whether an entry in the directory should be deleted /// - /// Default implementation always returns true, meaning all files and directories will be deleted. - /// This method and `should_keep` determine whether an entry should be deleted. + /// Default implementation always returns true, meaning all files and directories will be + /// deleted. This method and `should_keep` determine whether an entry should be deleted. /// If this method returns true and `should_keep` returns false, the entry will be deleted. /// Otherwise, the entry will not be deleted. #[allow(unused_variables)] @@ -180,15 +180,14 @@ fn del_item(path: &Path) -> Result<(), std::io::Error> { #[cfg(test)] mod tests { - use super::*; - - use crate::dirs::Ensure; - use std::{ collections::BTreeSet, env::{temp_dir, var_os}, }; + use super::*; + use crate::dirs::Ensure; + mod cleanup_target { use super::*; @@ -409,9 +408,10 @@ mod tests { #[cfg(feature = "core_installer")] { - use crate::installer::maa_core; use semver::Version; + use crate::installer::maa_core; + std::fs::File::create(join!( cache(), maa_core::name(&Version::new(0, 0, 1)).unwrap() diff --git a/maa-cli/src/command.rs b/maa-cli/src/command.rs index 6caf7cd3..a0b19fa8 100644 --- a/maa-cli/src/command.rs +++ b/maa-cli/src/command.rs @@ -1,10 +1,10 @@ -use crate::{cleanup, config, log, run}; - use std::path::PathBuf; use clap::{Parser, Subcommand, ValueEnum}; use clap_complete::Shell; +use crate::{cleanup, config, log, run}; + #[derive(Parser)] #[command(name = "maa", author, version = env!("MAA_VERSION"), about = "A tool for Arknights.")] #[allow(clippy::upper_case_acronyms)] @@ -176,8 +176,8 @@ pub(crate) enum Command { output: Option, /// Format of the output file, can be one of "toml", "yaml" and "json" /// - /// If not specified, the format will be guessed from the file extension of the output file. - /// If output file is not specified, the output will be default to "json". + /// If not specified, the format will be guessed from the file extension of the output + /// file. If output file is not specified, the output will be default to "json". #[arg(short, long)] format: Option, }, @@ -223,8 +223,8 @@ pub(crate) enum Command { /// - `resource`: user resource files. /// /// Other values are supported, but not recommended. - /// It will be treated as a subdirectory of the config directory and show a warning message. - /// If you think it is correct, please open an issue to let us know. + /// It will be treated as a subdirectory of the config directory and show a warning + /// message. If you think it is correct, please open an issue to let us know. #[arg(short = 't', long, default_value = "task", verbatim_doc_comment)] config_type: String, }, @@ -311,7 +311,6 @@ where #[cfg(test)] mod test { use super::*; - use crate::config::cli::Channel; #[macro_export] @@ -330,13 +329,10 @@ mod test { #[cfg(feature = "core_installer")] #[test] fn install() { - assert_matches!( - parse_from(["maa", "install"]).command, - Command::Install { - common: config::cli::maa_core::CommonArgs { .. }, - force: false, - } - ); + assert_matches!(parse_from(["maa", "install"]).command, Command::Install { + common: config::cli::maa_core::CommonArgs { .. }, + force: false, + }); assert_matches!( parse_from(["maa", "install", "beta"]).command, @@ -402,12 +398,9 @@ mod test { #[cfg(feature = "core_installer")] #[test] fn update() { - assert_matches!( - parse_from(["maa", "update"]).command, - Command::Update { - common: config::cli::maa_core::CommonArgs { .. }, - } - ); + assert_matches!(parse_from(["maa", "update"]).command, Command::Update { + common: config::cli::maa_core::CommonArgs { .. }, + }); } #[cfg(feature = "cli_installer")] @@ -443,26 +436,22 @@ mod test { #[test] fn dir() { - assert_matches!( - parse_from(["maa", "dir", "data"]).command, - Command::Dir { dir: Dir::Data } - ); + assert_matches!(parse_from(["maa", "dir", "data"]).command, Command::Dir { + dir: Dir::Data + }); assert_matches!( parse_from(["maa", "dir", "library"]).command, Command::Dir { dir: Dir::Library } ); - assert_matches!( - parse_from(["maa", "dir", "lib"]).command, - Command::Dir { dir: Dir::Library } - ); - assert_matches!( - parse_from(["maa", "dir", "config"]).command, - Command::Dir { dir: Dir::Config } - ); - assert_matches!( - parse_from(["maa", "dir", "cache"]).command, - Command::Dir { dir: Dir::Cache } - ); + assert_matches!(parse_from(["maa", "dir", "lib"]).command, Command::Dir { + dir: Dir::Library + }); + assert_matches!(parse_from(["maa", "dir", "config"]).command, Command::Dir { + dir: Dir::Config + }); + assert_matches!(parse_from(["maa", "dir", "cache"]).command, Command::Dir { + dir: Dir::Cache + }); assert_matches!( parse_from(["maa", "dir", "resource"]).command, Command::Dir { dir: Dir::Resource } @@ -473,20 +462,16 @@ mod test { dir: Dir::HotUpdate } ); - assert_matches!( - parse_from(["maa", "dir", "log"]).command, - Command::Dir { dir: Dir::Log } - ); + assert_matches!(parse_from(["maa", "dir", "log"]).command, Command::Dir { + dir: Dir::Log + }); } #[test] fn version() { - assert_matches!( - parse_from(["maa", "version"]).command, - Command::Version { - component: Component::All - } - ); + assert_matches!(parse_from(["maa", "version"]).command, Command::Version { + component: Component::All + }); assert_matches!( parse_from(["maa", "version", "all"]).command, Command::Version { @@ -604,12 +589,9 @@ mod test { #[test] fn activity() { - assert_matches!( - parse_from(["maa", "activity"]).command, - Command::Activity { - client: config::task::ClientType::Official, - } - ); + assert_matches!(parse_from(["maa", "activity"]).command, Command::Activity { + client: config::task::ClientType::Official, + }); assert_matches!( parse_from(["maa", "activity", "YoStarEN"]).command, @@ -689,14 +671,11 @@ mod test { #[test] fn init() { - assert_matches!( - parse_from(["maa", "init"]).command, - Command::Init { - name: None, - format: None, - force: false, - } - ); + assert_matches!(parse_from(["maa", "init"]).command, Command::Init { + name: None, + format: None, + force: false, + }); assert_matches!( parse_from(["maa", "init", "--name", "name"]).command, @@ -714,13 +693,10 @@ mod test { } ); - assert_matches!( - parse_from(["maa", "init", "-ft"]).command, - Command::Init { - format: Some(config::Filetype::Toml), - .. - } - ); + assert_matches!(parse_from(["maa", "init", "-ft"]).command, Command::Init { + format: Some(config::Filetype::Toml), + .. + }); assert_matches!( parse_from(["maa", "init", "--force"]).command, diff --git a/maa-cli/src/config/asst.rs b/maa-cli/src/config/asst.rs index a0a2231b..630b7b4a 100644 --- a/maa-cli/src/config/asst.rs +++ b/maa-cli/src/config/asst.rs @@ -1,5 +1,3 @@ -use crate::dirs; - use std::{borrow::Cow, path::PathBuf}; use anyhow::{Context, Result}; @@ -7,6 +5,8 @@ use log::{debug, info, warn}; use maa_sys::{Assistant, InstanceOptionKey, StaticOptionKey, TouchMode}; use serde::Deserialize; +use crate::dirs; + #[cfg_attr(test, derive(Debug, PartialEq))] #[derive(Default, Clone)] pub struct AsstConfig { @@ -223,10 +223,11 @@ fn config_based_on_os() -> &'static str { pub struct ResourceConfig { /// Resources used by global arknights client, e.g. `YostarEN` global_resource: Option, - /// Resources used by platform diff, subdirectories of `resource_base_dirs`, e.g. `platform_diff/iOS` + /// Resources used by platform diff, subdirectories of `resource_base_dirs`, e.g. + /// `platform_diff/iOS` platform_diff_resource: Option, - /// Whether to load resources from user config directory, when enabled, the `MAA_CONFIG_DIR/resource` - /// will be appended to `resource_base_dirs` as the last element + /// Whether to load resources from user config directory, when enabled, the + /// `MAA_CONFIG_DIR/resource` will be appended to `resource_base_dirs` as the last element user_resource: bool, /// Resource base directories, a list of directories containing resource directories /// Not deserialized from config file @@ -435,7 +436,7 @@ impl StaticOptions { .apply(true) .context("Failed to enable CPU OCR")?; } - (_, _) => {} + (..) => {} }; Ok(()) @@ -500,12 +501,11 @@ impl InstanceOptions { #[cfg(test)] mod tests { - use super::*; + use std::sync::OnceLock; + use super::*; use crate::assert_matches; - use std::sync::OnceLock; - fn user_resource_dir() -> PathBuf { static USER_RESOURCE_DIR: OnceLock = OnceLock::new(); USER_RESOURCE_DIR @@ -520,10 +520,10 @@ mod tests { } mod serde { - use super::*; - use serde_test::{assert_de_tokens, Token}; + use super::*; + #[test] #[ignore = "attempt to create a directory in user space"] fn deserialize_example() { @@ -534,45 +534,42 @@ mod tests { ) .unwrap(); - assert_eq!( - config, - AsstConfig { - connection: ConnectionConfig { - preset: Preset::ADB, - adb_path: Some(String::from("adb")), - address: Some(String::from("emulator-5554")), - config: Some(String::from("CompatMac")), - }, - resource: ResourceConfig { - resource_base_dirs: { - let mut base_dirs = default_resource_base_dirs(); - base_dirs.push(user_resource_dir); - base_dirs - }, - global_resource: Some(PathBuf::from("YoStarEN")), - platform_diff_resource: Some(PathBuf::from("iOS")), - user_resource: true, - }, - static_options: StaticOptions { - cpu_ocr: Some(false), - gpu_ocr: Some(1), - }, - instance_options: InstanceOptions { - touch_mode: Some(TouchMode::MaaTouch), - deployment_with_pause: Some(false), - adb_lite_enabled: Some(false), - kill_adb_on_exit: Some(false), + assert_eq!(config, AsstConfig { + connection: ConnectionConfig { + preset: Preset::ADB, + adb_path: Some(String::from("adb")), + address: Some(String::from("emulator-5554")), + config: Some(String::from("CompatMac")), + }, + resource: ResourceConfig { + resource_base_dirs: { + let mut base_dirs = default_resource_base_dirs(); + base_dirs.push(user_resource_dir); + base_dirs }, - } - ); + global_resource: Some(PathBuf::from("YoStarEN")), + platform_diff_resource: Some(PathBuf::from("iOS")), + user_resource: true, + }, + static_options: StaticOptions { + cpu_ocr: Some(false), + gpu_ocr: Some(1), + }, + instance_options: InstanceOptions { + touch_mode: Some(TouchMode::MaaTouch), + deployment_with_pause: Some(false), + adb_lite_enabled: Some(false), + kill_adb_on_exit: Some(false), + }, + }); } #[test] fn connection_config() { - assert_de_tokens( - &ConnectionConfig::default(), - &[Token::Map { len: Some(0) }, Token::MapEnd], - ); + assert_de_tokens(&ConnectionConfig::default(), &[ + Token::Map { len: Some(0) }, + Token::MapEnd, + ]); assert_de_tokens( &ConnectionConfig { @@ -808,15 +805,12 @@ mod tests { #[test] fn default() { - assert_matches!( - ConnectionConfig::default(), - ConnectionConfig { - preset: Preset::ADB, - adb_path: None, - address: None, - config: None, - } - ); + assert_matches!(ConnectionConfig::default(), ConnectionConfig { + preset: Preset::ADB, + adb_path: None, + address: None, + config: None, + }); } #[cfg(target_os = "macos")] @@ -936,23 +930,19 @@ mod tests { } mod resource_config { - use super::*; + use std::{env::temp_dir, fs}; + use super::*; use crate::dirs::Ensure; - use std::{env::temp_dir, fs}; - #[test] fn default() { - assert_eq!( - ResourceConfig::default(), - ResourceConfig { - resource_base_dirs: default_resource_base_dirs(), - global_resource: None, - platform_diff_resource: None, - user_resource: false, - } - ); + assert_eq!(ResourceConfig::default(), ResourceConfig { + resource_base_dirs: default_resource_base_dirs(), + global_resource: None, + platform_diff_resource: None, + user_resource: false, + }); } #[test] @@ -1043,10 +1033,9 @@ mod tests { resource_dir.ensure().unwrap(); - assert_eq!( - push_resource(&mut Vec::new(), resource_dir.clone()), - &[resource_dir.clone()] - ); + assert_eq!(push_resource(&mut Vec::new(), resource_dir.clone()), &[ + resource_dir.clone() + ]); assert_eq!( push_resource(&mut Vec::new(), unexists_resource_dir.clone()), diff --git a/maa-cli/src/config/cli/maa_cli.rs b/maa-cli/src/config/cli/maa_cli.rs index 99cb10f6..c7c42540 100644 --- a/maa-cli/src/config/cli/maa_cli.rs +++ b/maa-cli/src/config/cli/maa_cli.rs @@ -1,8 +1,8 @@ -use super::{normalize_url, return_true, Channel}; - use clap::Args; use serde::Deserialize; +use super::{normalize_url, return_true, Channel}; + #[cfg_attr(test, derive(Debug, PartialEq))] #[derive(Deserialize, Clone)] pub struct Config { @@ -132,25 +132,22 @@ pub mod tests { } mod serde { - use super::*; - use serde_test::{assert_de_tokens, Token}; + use super::*; + #[test] fn deserialize_cli_components() { - assert_de_tokens( - &CLIComponents { binary: true }, - &[Token::Map { len: Some(0) }, Token::MapEnd], - ); - assert_de_tokens( - &CLIComponents { binary: false }, - &[ - Token::Map { len: Some(1) }, - Token::Str("binary"), - Token::Bool(false), - Token::MapEnd, - ], - ); + assert_de_tokens(&CLIComponents { binary: true }, &[ + Token::Map { len: Some(0) }, + Token::MapEnd, + ]); + assert_de_tokens(&CLIComponents { binary: false }, &[ + Token::Map { len: Some(1) }, + Token::Str("binary"), + Token::Bool(false), + Token::MapEnd, + ]); } #[test] @@ -179,10 +176,10 @@ pub mod tests { ], ); - assert_de_tokens( - &Config::default(), - &[Token::Map { len: Some(0) }, Token::MapEnd], - ); + assert_de_tokens(&Config::default(), &[ + Token::Map { len: Some(0) }, + Token::MapEnd, + ]); } } @@ -240,10 +237,9 @@ pub mod tests { #[test] fn components() { - assert_eq!( - Config::default().components(), - &CLIComponents { binary: true }, - ); + assert_eq!(Config::default().components(), &CLIComponents { + binary: true + },); assert_eq!( Config { diff --git a/maa-cli/src/config/cli/maa_core.rs b/maa-cli/src/config/cli/maa_core.rs index 63c48d34..c4306b78 100644 --- a/maa-cli/src/config/cli/maa_core.rs +++ b/maa-cli/src/config/cli/maa_core.rs @@ -1,8 +1,8 @@ -use super::{normalize_url, return_true, Channel}; - use clap::Args; use serde::Deserialize; +use super::{normalize_url, return_true, Channel}; + #[cfg_attr(test, derive(Debug, PartialEq))] #[derive(Deserialize, Clone)] pub struct Config { @@ -157,10 +157,10 @@ pub struct CommonArgs { #[cfg(test)] pub mod tests { - use super::*; - use std::sync::OnceLock; + use super::*; + pub fn example_config() -> Config { Config { channel: Channel::Beta, @@ -179,10 +179,10 @@ pub mod tests { } mod serde { - use super::*; - use serde_test::{assert_de_tokens, Token}; + use super::*; + #[test] fn deserialize_components() { assert_de_tokens( @@ -223,10 +223,10 @@ pub mod tests { &[Token::Map { len: Some(0) }, Token::MapEnd], ); - assert_de_tokens( - &default_config(), - &[Token::Map { len: Some(0) }, Token::MapEnd], - ); + assert_de_tokens(&default_config(), &[ + Token::Map { len: Some(0) }, + Token::MapEnd, + ]); assert_de_tokens( &Config { diff --git a/maa-cli/src/config/cli/mod.rs b/maa-cli/src/config/cli/mod.rs index f0447c0b..85a1cdf1 100644 --- a/maa-cli/src/config/cli/mod.rs +++ b/maa-cli/src/config/cli/mod.rs @@ -5,15 +5,14 @@ pub mod maa_core; pub mod resource; -use super::FindFileOrDefault; - -use crate::dirs; - use std::sync::OnceLock; use clap::ValueEnum; use serde::Deserialize; +use super::FindFileOrDefault; +use crate::dirs; + /// Configuration for the CLI (cli.toml) #[cfg_attr(test, derive(Debug, PartialEq))] #[derive(Deserialize, Default)] @@ -89,12 +88,12 @@ fn normalize_url(url: &str) -> String { #[cfg(test)] mod tests { - use super::{resource::GitBackend, *}; - use serde_json; use serde_test::{assert_de_tokens, Token}; use toml; + use super::{resource::GitBackend, *}; + // The serde_de_token cannot deserialize "beta" to Channel::Beta // But it works in real implementation (serde_json::from_str) // So we have to use this workaround @@ -124,10 +123,10 @@ mod tests { #[test] fn deserialize_installer_config() { - assert_de_tokens( - &CLIConfig::default(), - &[Token::Map { len: Some(0) }, Token::MapEnd], - ); + assert_de_tokens(&CLIConfig::default(), &[ + Token::Map { len: Some(0) }, + Token::MapEnd, + ]); #[cfg(feature = "core_installer")] assert_de_tokens( diff --git a/maa-cli/src/config/cli/resource.rs b/maa-cli/src/config/cli/resource.rs index 2fefa5b2..3abfe3f3 100644 --- a/maa-cli/src/config/cli/resource.rs +++ b/maa-cli/src/config/cli/resource.rs @@ -101,24 +101,22 @@ pub mod tests { #[test] fn default() { let config = Config::default(); - assert_eq!( - config, - Config { - auto_update: false, - backend: GitBackend::Git, - remote: Remote { - url: default_url(), - branch: None, - ssh_key: None, - } + assert_eq!(config, Config { + auto_update: false, + backend: GitBackend::Git, + remote: Remote { + url: default_url(), + branch: None, + ssh_key: None, } - ); + }); } mod serde { - use super::*; use serde_test::{assert_de_tokens, Token}; + use super::*; + impl GitBackend { pub fn to_token(self) -> Token { Token::UnitVariant { @@ -142,10 +140,10 @@ pub mod tests { #[test] fn remote() { - assert_de_tokens( - &Remote::default(), - &[Token::Map { len: Some(0) }, Token::MapEnd], - ); + assert_de_tokens(&Remote::default(), &[ + Token::Map { len: Some(0) }, + Token::MapEnd, + ]); assert_de_tokens( &Remote { @@ -170,10 +168,10 @@ pub mod tests { #[test] fn config() { - assert_de_tokens( - &Config::default(), - &[Token::Map { len: Some(0) }, Token::MapEnd], - ); + assert_de_tokens(&Config::default(), &[ + Token::Map { len: Some(0) }, + Token::MapEnd, + ]); assert_de_tokens( &Config { diff --git a/maa-cli/src/config/init.rs b/maa-cli/src/config/init.rs index f12e669d..1418d566 100644 --- a/maa-cli/src/config/init.rs +++ b/maa-cli/src/config/init.rs @@ -1,3 +1,7 @@ +use std::path::PathBuf; + +use anyhow::{bail, Result}; + use crate::{ object, value::{ @@ -6,10 +10,6 @@ use crate::{ }, }; -use std::path::PathBuf; - -use anyhow::{bail, Result}; - fn asst_config_template() -> MAAValue { object!( "setup_connection" => BoolInput::new(Some(true), Some("setup connection")), @@ -236,9 +236,7 @@ pub fn init(name: Option, filetype: Option, force: boo #[cfg(test)] mod test { - use super::*; - - use super::super::Filetype; + use super::{super::Filetype, *}; #[test] #[ignore = "write to user's config directory"] diff --git a/maa-cli/src/config/mod.rs b/maa-cli/src/config/mod.rs index e03c789f..c3843f12 100644 --- a/maa-cli/src/config/mod.rs +++ b/maa-cli/src/config/mod.rs @@ -1,10 +1,12 @@ -use crate::dirs::{self, Ensure}; - -use std::fs::{self, File}; -use std::path::Path; +use std::{ + fs::{self, File}, + path::Path, +}; use serde_json::Value as JsonValue; +use crate::dirs::{self, Ensure}; + #[derive(Debug)] pub enum Error { UnsupportedFiletype, @@ -351,14 +353,14 @@ pub mod init; #[cfg(test)] mod tests { - use super::*; use std::env::temp_dir; - use crate::assert_matches; - use serde::Deserialize; use serde_json::{json, Value as JsonValue}; + use super::*; + use crate::assert_matches; + #[test] fn filetype() { use Filetype::*; @@ -435,13 +437,10 @@ mod tests { } ); - assert_eq!( - TestConfig::find_file(&test_file).unwrap(), - TestConfig { - a: 1, - b: "test".to_string() - } - ); + assert_eq!(TestConfig::find_file(&test_file).unwrap(), TestConfig { + a: 1, + b: "test".to_string() + }); assert_matches!( TestConfig::find_file(&non_exist_file).unwrap_err(), diff --git a/maa-cli/src/config/task/client_type.rs b/maa-cli/src/config/task/client_type.rs index 9bf11152..e06ba346 100644 --- a/maa-cli/src/config/task/client_type.rs +++ b/maa-cli/src/config/task/client_type.rs @@ -19,6 +19,15 @@ use ClientType::*; impl ClientType { pub const COUNT: usize = 6; + pub const NAMES: [&'static str; Self::COUNT] = { + let mut i = 0; + let mut names = ["Official"; Self::COUNT]; + while i < Self::COUNT { + names[i] = Self::VARIANTS[i].to_str(); + i += 1; + } + names + }; pub const VARIANTS: [ClientType; Self::COUNT] = { let mut i = 0; let mut variants = [Official; Self::COUNT]; @@ -40,16 +49,6 @@ impl ClientType { } } - pub const NAMES: [&'static str; Self::COUNT] = { - let mut i = 0; - let mut names = ["Official"; Self::COUNT]; - while i < Self::COUNT { - names[i] = Self::VARIANTS[i].to_str(); - i += 1; - } - names - }; - fn from_str_opt(s: &str) -> Option { // Default to Official if empty if s.is_empty() { @@ -151,10 +150,10 @@ impl std::error::Error for UnknownClientTypeError {} #[cfg(test)] mod tests { - use super::*; - use serde_test::{assert_de_tokens, assert_de_tokens_error, Token}; + use super::*; + impl ClientType { const fn to_token(self) -> Token { Token::Str(self.to_str()) diff --git a/maa-cli/src/config/task/condition.rs b/maa-cli/src/config/task/condition.rs index 9e70284a..271dbfb9 100644 --- a/maa-cli/src/config/task/condition.rs +++ b/maa-cli/src/config/task/condition.rs @@ -1,10 +1,9 @@ -use super::client_type::ClientType; - -use crate::activity::has_side_story_open; - use chrono::{DateTime, Datelike, NaiveDateTime, NaiveTime, TimeZone, Utc, Weekday}; use serde::Deserialize; +use super::client_type::ClientType; +use crate::activity::has_side_story_open; + #[cfg_attr(test, derive(PartialEq, Debug))] #[derive(Deserialize)] #[serde(tag = "type")] @@ -16,8 +15,9 @@ pub enum Condition { /// The task is active on the specified weekdays /// /// By default, use the weekday in user local time zone. - /// If client is specified, use the weekday in the server time zone and start of the day will be - /// 04:00:00 instead of 00:00:00 in server time zone, and the end of the day will be 03:59:59. + /// If client is specified, use the weekday in the server time zone and start of the day will + /// be 04:00:00 instead of 00:00:00 in server time zone, and the end of the day will be + /// 03:59:59. Weekday { weekdays: Vec, #[serde(default, alias = "client")] @@ -182,9 +182,10 @@ pub fn remainder_of_day_mod(tz: TimeOffset, divisor: u32) -> u32 { #[cfg(test)] mod tests { - use super::*; use chrono::{Local, TimeZone}; + use super::*; + fn naive_local_datetime(y: i32, m: u32, d: u32, h: u32, mi: u32, s: u32) -> NaiveDateTime { Local .with_ymd_and_hms(y, m, d, h, mi, s) @@ -193,9 +194,10 @@ mod tests { } mod active { - use super::*; use chrono::{Duration, FixedOffset, NaiveDate}; + use super::*; + #[test] fn always() { assert!(Condition::Always.is_active()); @@ -315,9 +317,10 @@ mod tests { naive_date(2024, 2, 14), ); - // This is a very unusual case that the local time zone is UTC+14 and server time zone is UTC-7 - // For local time 2024-02-15 00:00:00, the server time is 2024-02-14 03:00:00 - // Thus the game date is 2024-02-13 even though the local date is 2024-02-15 + // This is a very unusual case that the local time zone is UTC+14 and server time zone + // is UTC-7 For local time 2024-02-15 00:00:00, the server time is + // 2024-02-14 03:00:00 Thus the game date is 2024-02-13 even though the + // local date is 2024-02-15 assert_eq!( game_date(datetime(14, 2024, 2, 15, 0, 0), ClientType::YoStarEN), naive_date(2024, 2, 13), @@ -523,22 +526,16 @@ mod tests { } .is_active()); assert!(!Condition::And { - conditions: vec![ - Condition::Always, - Condition::Not { - condition: Box::new(Condition::Always) - }, - ] + conditions: vec![Condition::Always, Condition::Not { + condition: Box::new(Condition::Always) + },] } .is_active()); assert!(Condition::Or { - conditions: vec![ - Condition::Always, - Condition::Not { - condition: Box::new(Condition::Always) - } - ] + conditions: vec![Condition::Always, Condition::Not { + condition: Box::new(Condition::Always) + }] } .is_active()); @@ -562,9 +559,10 @@ mod tests { } mod serde { - use super::*; use serde_test::{assert_de_tokens, Token}; + use super::*; + #[test] fn weekday() { assert_de_tokens( @@ -637,31 +635,25 @@ mod tests { timezone: TimeOffset::Local, }; - assert_de_tokens( - &cond, - &[ - Token::Map { len: Some(3) }, - Token::Str("type"), - Token::Str("DayMod"), - Token::Str("divisor"), - Token::U32(7), - Token::Str("remainder"), - Token::U32(0), - Token::MapEnd, - ], - ); - - assert_de_tokens( - &cond, - &[ - Token::Map { len: Some(2) }, - Token::Str("type"), - Token::Str("DayMod"), - Token::Str("divisor"), - Token::U32(7), - Token::MapEnd, - ], - ); + assert_de_tokens(&cond, &[ + Token::Map { len: Some(3) }, + Token::Str("type"), + Token::Str("DayMod"), + Token::Str("divisor"), + Token::U32(7), + Token::Str("remainder"), + Token::U32(0), + Token::MapEnd, + ]); + + assert_de_tokens(&cond, &[ + Token::Map { len: Some(2) }, + Token::Str("type"), + Token::Str("DayMod"), + Token::Str("divisor"), + Token::U32(7), + Token::MapEnd, + ]); } #[test] diff --git a/maa-cli/src/config/task/mod.rs b/maa-cli/src/config/task/mod.rs index 832feddd..6b1188e4 100644 --- a/maa-cli/src/config/task/mod.rs +++ b/maa-cli/src/config/task/mod.rs @@ -2,17 +2,16 @@ mod client_type; pub use client_type::ClientType; mod condition; -use condition::Condition; -pub use condition::{remainder_of_day_mod, TimeOffset}; - -use crate::{dirs, object, value::MAAValue}; - use std::path::PathBuf; use anyhow::Context; +use condition::Condition; +pub use condition::{remainder_of_day_mod, TimeOffset}; use maa_sys::TaskType; use serde::Deserialize; +use crate::{dirs, object, value::MAAValue}; + #[cfg_attr(test, derive(PartialEq, Debug))] #[derive(Deserialize, Default)] #[serde(deny_unknown_fields)] @@ -340,7 +339,6 @@ impl InitializedTask { #[cfg(test)] mod tests { use super::*; - use crate::object; mod task { @@ -492,19 +490,17 @@ mod tests { } mod task_config { - use super::*; - use TaskType::*; - mod serde { - use super::*; + use super::*; + mod serde { + use chrono::{NaiveDateTime, NaiveTime, TimeZone, Weekday}; use condition::TimeOffset; + use super::*; use crate::value::userinput::{BoolInput, Input, SelectD}; - use chrono::{NaiveDateTime, NaiveTime, TimeZone, Weekday}; - fn naive_local_datetime( y: i32, m: u32, diff --git a/maa-cli/src/installer/download.rs b/maa-cli/src/installer/download.rs index bf4c2abe..96cec0e9 100644 --- a/maa-cli/src/installer/download.rs +++ b/maa-cli/src/installer/download.rs @@ -1,14 +1,15 @@ -use log::debug; - -use std::cmp::min; -use std::fs::{remove_file, File}; -use std::io::Write; -use std::path::Path; -use std::time::{Duration, Instant}; +use std::{ + cmp::min, + fs::{remove_file, File}, + io::Write, + path::Path, + time::{Duration, Instant}, +}; use digest::Digest; use futures_util::StreamExt; use indicatif::{ProgressBar, ProgressStyle}; +use log::debug; use reqwest::Client; use sha2::Sha256; diff --git a/maa-cli/src/installer/extract.rs b/maa-cli/src/installer/extract.rs index b822f373..ee5efd27 100644 --- a/maa-cli/src/installer/extract.rs +++ b/maa-cli/src/installer/extract.rs @@ -1,5 +1,3 @@ -use crate::dirs::Ensure; - use std::{ borrow::Cow, fs::File, @@ -9,6 +7,8 @@ use std::{ use anyhow::{anyhow, bail, Context, Result}; +use crate::dirs::Ensure; + /// Supported archive types. /// /// Currently only zip and tar.gz are supported. @@ -135,8 +135,10 @@ fn extract_zip(file: &Path, mapper: impl Fn(&Path) -> Option) -> Result #[cfg(unix)] { - use std::fs::{set_permissions, Permissions}; - use std::os::unix::fs::PermissionsExt; + use std::{ + fs::{set_permissions, Permissions}, + os::unix::fs::PermissionsExt, + }; if let Some(mode) = file.unix_mode() { set_permissions(&outpath, Permissions::from_mode(mode)) diff --git a/maa-cli/src/installer/maa_cli.rs b/maa-cli/src/installer/maa_cli.rs index 02397477..54c2ba90 100644 --- a/maa-cli/src/installer/maa_cli.rs +++ b/maa-cli/src/installer/maa_cli.rs @@ -1,14 +1,3 @@ -use super::{ - download::{download, Checker}, - extract::Archive, - version_json::VersionJSON, -}; - -use crate::{ - config::cli::{cli_config, maa_cli::CommonArgs}, - dirs::{self, Ensure}, -}; - use std::{ env::{consts, current_exe}, time::Duration, @@ -20,6 +9,16 @@ use semver::Version; use serde::Deserialize; use tokio::runtime::Runtime; +use super::{ + download::{download, Checker}, + extract::Archive, + version_json::VersionJSON, +}; +use crate::{ + config::cli::{cli_config, maa_cli::CommonArgs}, + dirs::{self, Ensure}, +}; + pub fn update(args: &CommonArgs) -> Result<()> { let config = cli_config().cli_config().with_args(args); @@ -146,10 +145,10 @@ impl Asset { #[cfg(test)] mod tests { - use super::*; - use serde_json; + use super::*; + #[test] fn deserialize_version_json() { let json = r#" diff --git a/maa-cli/src/installer/maa_core.rs b/maa-cli/src/installer/maa_core.rs index b5512ede..32e6b444 100644 --- a/maa-cli/src/installer/maa_core.rs +++ b/maa-cli/src/installer/maa_core.rs @@ -1,11 +1,23 @@ // This file is used to download and extract prebuilt packages of maa-core. +use std::{ + borrow::Cow, + env::consts::{ARCH, DLL_PREFIX, DLL_SUFFIX, OS}, + path::{self, Path, PathBuf}, + time::Duration, +}; + +use anyhow::{anyhow, bail, Context, Result}; +use log::debug; +use semver::Version; +use serde::Deserialize; +use tokio::runtime::Runtime; + use super::{ download::{check_file_exists, download_mirrors}, extract::Archive, version_json::VersionJSON, }; - use crate::{ config::cli::{ cli_config, @@ -15,19 +27,6 @@ use crate::{ run, }; -use std::{ - borrow::Cow, - env::consts::{ARCH, DLL_PREFIX, DLL_SUFFIX, OS}, - path::{self, Path, PathBuf}, - time::Duration, -}; - -use anyhow::{anyhow, bail, Context, Result}; -use log::debug; -use semver::Version; -use serde::Deserialize; -use tokio::runtime::Runtime; - fn extract_mapper( src: &Path, lib_dir: &Path, @@ -284,10 +283,10 @@ pub fn download<'p>( #[cfg(test)] mod tests { - use super::*; - use serde_json; + use super::*; + #[test] fn deserialize_version_json() { // This is a stripped version of the real json diff --git a/maa-cli/src/installer/resource.rs b/maa-cli/src/installer/resource.rs index a049d3ec..b203a129 100644 --- a/maa-cli/src/installer/resource.rs +++ b/maa-cli/src/installer/resource.rs @@ -1,11 +1,11 @@ +use anyhow::{bail, Result}; +use log::{debug, warn}; + use crate::{ config::cli::{cli_config, resource::GitBackend}, dirs, }; -use anyhow::{bail, Result}; -use log::{debug, warn}; - trait StatusExt { /// If error, return the error, otherwise return an error if the status is not successful fn check(self) -> std::io::Result<()>; @@ -89,12 +89,12 @@ pub fn update(is_auto: bool) -> Result<()> { } mod git { - use super::StatusExt; - use std::path::Path; use anyhow::{Context, Result}; + use super::StatusExt; + pub fn clone( url: &str, branch: Option<&str>, diff --git a/maa-cli/src/log.rs b/maa-cli/src/log.rs index 57497277..3b6d4c94 100644 --- a/maa-cli/src/log.rs +++ b/maa-cli/src/log.rs @@ -164,10 +164,10 @@ mod tests { use super::*; mod cmd_args { - use crate::command::parse_from; - use std::env; + use crate::command::parse_from; + #[test] fn to_filter() { env::remove_var("MAA_LOG"); diff --git a/maa-cli/src/main.rs b/maa-cli/src/main.rs index 8cfd36f7..53cc8801 100644 --- a/maa-cli/src/main.rs +++ b/maa-cli/src/main.rs @@ -12,11 +12,11 @@ mod installer; mod run; mod value; -use crate::command::{Command, Component, Dir, CLI}; - use anyhow::{Context, Result}; use clap::{CommandFactory, Parser}; +use crate::command::{Command, Component, Dir, CLI}; + fn main() -> Result<()> { let cli = command::CLI::parse(); diff --git a/maa-cli/src/run/callback/mod.rs b/maa-cli/src/run/callback/mod.rs index fe17a39b..2dba6e5c 100644 --- a/maa-cli/src/run/callback/mod.rs +++ b/maa-cli/src/run/callback/mod.rs @@ -1,11 +1,10 @@ pub mod summary; -use summary::{edit_current_task_detail, end_current_task, start_task}; - use std::{fmt::Write, sync::atomic::AtomicBool}; use log::{debug, error, info, trace, warn}; use maa_sys::binding::{AsstMsgId, AsstTaskId}; use serde_json::{Map, Value}; +use summary::{edit_current_task_detail, end_current_task, start_task}; pub static MAA_CORE_ERRORED: AtomicBool = AtomicBool::new(false); diff --git a/maa-cli/src/run/callback/summary.rs b/maa-cli/src/run/callback/summary.rs index 8ee5342a..cea89838 100644 --- a/maa-cli/src/run/callback/summary.rs +++ b/maa-cli/src/run/callback/summary.rs @@ -1,11 +1,11 @@ -use super::IterJoin; - pub use std::collections::BTreeMap as Map; use std::sync::Mutex; use chrono; use maa_sys::{binding::AsstTaskId, TaskType}; +use super::IterJoin; + static SUMMARY: Mutex> = Mutex::new(None); // It's safe to unwarp the mutex all there, because lock() returns a error only when @@ -454,7 +454,8 @@ impl std::fmt::Display for InfrastRoomInfo { write!( f, ", [{}]", - self.candidates.iter().join(", ").unwrap() // safe to unwrap, because it's not empty + self.candidates.iter().join(", ").unwrap() /* safe to unwrap, because it's not + * empty */ )?; } Ok(()) @@ -724,9 +725,11 @@ impl ExplorationState { Unknown => "Unknown", } } + const fn total_type() -> usize { 4 } + const fn to_index(self) -> usize { self as usize } @@ -842,7 +845,6 @@ mod tests { use regex::Regex; use super::*; - use crate::assert_matches; #[test] @@ -928,9 +930,8 @@ mod tests { } mod detail { - use crate::assert_matches; - use super::*; + use crate::assert_matches; #[test] fn detail() { diff --git a/maa-cli/src/run/external/playcover.rs b/maa-cli/src/run/external/playcover.rs index 1ae18ab8..3501f113 100644 --- a/maa-cli/src/run/external/playcover.rs +++ b/maa-cli/src/run/external/playcover.rs @@ -1,9 +1,9 @@ -use crate::config::task::ClientType; - use anyhow::{Context, Result}; use log::{info, trace}; use tokio::net::TcpStream; +use crate::config::task::ClientType; + #[cfg_attr(test, derive(PartialEq, Debug))] pub struct PlayCoverApp<'a> { client: ClientType, diff --git a/maa-cli/src/run/mod.rs b/maa-cli/src/run/mod.rs index bc240466..a475cf55 100644 --- a/maa-cli/src/run/mod.rs +++ b/maa-cli/src/run/mod.rs @@ -8,11 +8,6 @@ mod external; pub mod preset; -use crate::{ - config::{asst::AsstConfig, task::TaskConfig, FindFile}, - installer::resource, -}; - use std::{ path::Path, sync::{atomic, Arc}, @@ -25,6 +20,11 @@ use maa_dirs::{self as dirs, Ensure, MAA_CORE_LIB}; use maa_sys::Assistant; use signal_hook::consts::TERM_SIGNALS; +use crate::{ + config::{asst::AsstConfig, task::TaskConfig, FindFile}, + installer::resource, +}; + #[cfg_attr(test, derive(Debug, PartialEq))] #[derive(Args, Default)] pub struct CommonArgs { @@ -312,10 +312,10 @@ fn setup_core(config: &AsstConfig) -> Result<()> { #[cfg(test)] mod tests { - use super::*; - use std::env::{self, temp_dir}; + use super::*; + #[test] #[ignore = "need installed MaaCore"] fn version() { diff --git a/maa-cli/src/run/preset/copilot.rs b/maa-cli/src/run/preset/copilot.rs index 2ab223b3..ea0d6587 100644 --- a/maa-cli/src/run/preset/copilot.rs +++ b/maa-cli/src/run/preset/copilot.rs @@ -1,5 +1,12 @@ -use super::{FindFileOrDefault, IntoTaskConfig, ToTaskType}; +use std::{borrow::Cow, fs, io::Write, path::Path}; +use anyhow::{bail, Context, Result}; +use log::{debug, trace}; +use maa_sys::TaskType; +use prettytable::{format, row, Table}; +use serde_json::Value as JsonValue; + +use super::{FindFileOrDefault, IntoTaskConfig, ToTaskType}; use crate::{ config::task::{Task, TaskConfig}, dirs::{self, Ensure}, @@ -10,21 +17,13 @@ use crate::{ }, }; -use std::{borrow::Cow, fs, io::Write, path::Path}; - -use anyhow::{bail, Context, Result}; -use log::{debug, trace}; -use maa_sys::TaskType; -use prettytable::{format, row, Table}; -use serde_json::Value as JsonValue; - #[cfg_attr(test, derive(Default))] #[derive(clap::Args)] pub struct CopilotParams { /// URI of the copilot task file /// - /// It can be a maa URI or a local file path. Multiple URIs can be provided to fight multiple stages. - /// For URI, it can be in the format of `maa://`, `maa://s`, `file://`, + /// It can be a maa URI or a local file path. Multiple URIs can be provided to fight multiple + /// stages. For URI, it can be in the format of `maa://`, `maa://s`, `file://`, /// which represents a single copilot task, a copilot task set, and a local file respectively. uri_list: Vec, /// Whether to fight stage in raid mode @@ -34,8 +33,8 @@ pub struct CopilotParams { raid: u8, /// Whether to auto formation /// - /// When multiple uri are provided or a copilot task set contains multiple stages, force to true. - /// Otherwise, default to false. + /// When multiple uri are provided or a copilot task set contains multiple stages, force to + /// true. Otherwise, default to false. #[arg(long)] formation: bool, /// Whether to use sanity potion to restore sanity when it's not enough @@ -431,13 +430,11 @@ fn get_str_key(value: &JsonValue, key: impl AsRef) -> Result<&str> { #[cfg(test)] mod tests { - use super::*; + use std::{env::temp_dir, path::PathBuf}; + use super::*; use crate::config::asst::AsstConfig; - use std::env::temp_dir; - use std::path::PathBuf; - macro_rules! assert_params { ($params:expr, $expected:expr $(,)?) => { let mut params = $params.clone(); diff --git a/maa-cli/src/run/preset/fight.rs b/maa-cli/src/run/preset/fight.rs index 65651f0b..09e4d0d5 100644 --- a/maa-cli/src/run/preset/fight.rs +++ b/maa-cli/src/run/preset/fight.rs @@ -1,9 +1,8 @@ -use super::MAAValue; +use anyhow::{bail, Context}; +use super::MAAValue; use crate::config::task::ClientType; -use anyhow::{bail, Context}; - #[derive(clap::Args)] pub struct FightParams { /// Stage to fight, e.g. 1-7, leave empty to fight current/last stage @@ -126,7 +125,6 @@ impl TryFrom for MAAValue { #[cfg(test)] mod tests { use super::*; - use crate::{ command::{parse_from, Command}, object, diff --git a/maa-cli/src/run/preset/mod.rs b/maa-cli/src/run/preset/mod.rs index 18ddfa03..4b711ca6 100644 --- a/maa-cli/src/run/preset/mod.rs +++ b/maa-cli/src/run/preset/mod.rs @@ -1,3 +1,6 @@ +use anyhow::{Context, Result}; +use maa_sys::TaskType; + use crate::{ config::{ asst::AsstConfig, @@ -7,9 +10,6 @@ use crate::{ value::MAAValue, }; -use anyhow::{Context, Result}; -use maa_sys::TaskType; - fn default_file(task_type: TaskType) -> std::path::PathBuf { maa_dirs::join!( maa_dirs::config(), @@ -110,15 +110,14 @@ pub use reclamation::ReclamationParams; #[cfg(test)] mod tests { - use super::*; + use maa_dirs::Ensure; + use super::*; use crate::{ command::{parse_from, Command}, object, }; - use maa_dirs::Ensure; - impl MAAValue { /// Merge another value into this default value. /// diff --git a/maa-cli/src/run/preset/reclamation.rs b/maa-cli/src/run/preset/reclamation.rs index 4ae5c1fe..cb7945fd 100644 --- a/maa-cli/src/run/preset/reclamation.rs +++ b/maa-cli/src/run/preset/reclamation.rs @@ -1,7 +1,7 @@ -use super::MAAValue; - use color_print::cstr; +use super::MAAValue; + #[repr(u8)] #[cfg_attr(test, derive(Debug, PartialEq))] #[derive(Clone, Copy)] @@ -87,10 +87,10 @@ mod tests { use super::*; mod theme { - use super::*; - use clap::ValueEnum; + use super::*; + #[test] fn to_str() { assert_eq!(Theme::Tales.to_str(), "Tales"); diff --git a/maa-cli/src/run/preset/roguelike.rs b/maa-cli/src/run/preset/roguelike.rs index 2d7b322c..d92db375 100644 --- a/maa-cli/src/run/preset/roguelike.rs +++ b/maa-cli/src/run/preset/roguelike.rs @@ -1,8 +1,8 @@ -use super::MAAValue; - use anyhow::bail; use clap::ValueEnum; +use super::MAAValue; + #[repr(i8)] #[cfg_attr(test, derive(PartialEq, Debug))] #[derive(Clone, Copy)] @@ -58,7 +58,8 @@ pub struct RoguelikeParams { /// Starting core operator in Chinese, e.g. "维什戴尔" #[arg(long)] core_char: Option, - /// Starting operators recruitment combination in Chinese, e.g. "取长补短", "先手必胜" (default) + /// Starting operators recruitment combination in Chinese, e.g. "取长补短", "先手必胜" + /// (default) #[arg(long)] roles: Option, @@ -231,7 +232,6 @@ impl TryFrom for MAAValue { #[cfg(test)] mod tests { use super::*; - use crate::{ command::{parse_from, Command}, object, @@ -251,10 +251,12 @@ mod tests { #[test] fn value_variants() { - assert_eq!( - Theme::value_variants(), - &[Theme::Phantom, Theme::Mizuki, Theme::Sami, Theme::Sarkaz] - ); + assert_eq!(Theme::value_variants(), &[ + Theme::Phantom, + Theme::Mizuki, + Theme::Sami, + Theme::Sarkaz + ]); } #[test] diff --git a/maa-cli/src/value/input.rs b/maa-cli/src/value/input.rs index 6477794d..e61c5901 100644 --- a/maa-cli/src/value/input.rs +++ b/maa-cli/src/value/input.rs @@ -1,13 +1,13 @@ +use std::io; + +use serde::Deserialize; + use super::{ primate::MAAPrimate, userinput::{BoolInput, Input, SelectD, UserInput}, MAAValue, }; -use std::io; - -use serde::Deserialize; - #[cfg_attr(test, derive(PartialEq, Debug))] #[derive(Deserialize, Clone)] #[serde(untagged)] @@ -128,56 +128,53 @@ mod tests { .into(), ]; - assert_de_tokens( - &values, - &[ - Token::Seq { len: Some(7) }, - Token::Map { len: Some(1) }, - Token::String("default"), - Token::Bool(true), - Token::MapEnd, - Token::Map { len: Some(1) }, - Token::String("default"), - Token::I32(1), - Token::MapEnd, - Token::Map { len: Some(1) }, - Token::String("default"), - Token::F32(1.0), - Token::MapEnd, - Token::Map { len: Some(1) }, - Token::String("default"), - Token::String("1"), - Token::MapEnd, - Token::Map { len: Some(2) }, - Token::String("default_index"), - Token::U64(2), - Token::String("alternatives"), - Token::Seq { len: Some(2) }, - Token::I32(1), - Token::I32(2), - Token::SeqEnd, - Token::MapEnd, - Token::Map { len: Some(2) }, - Token::String("default_index"), - Token::U64(2), - Token::String("alternatives"), - Token::Seq { len: Some(2) }, - Token::F32(1.0), - Token::F32(2.0), - Token::SeqEnd, - Token::MapEnd, - Token::Map { len: Some(2) }, - Token::String("default_index"), - Token::U64(2), - Token::String("alternatives"), - Token::Seq { len: Some(2) }, - Token::String("1"), - Token::String("2"), - Token::SeqEnd, - Token::MapEnd, - Token::SeqEnd, - ], - ); + assert_de_tokens(&values, &[ + Token::Seq { len: Some(7) }, + Token::Map { len: Some(1) }, + Token::String("default"), + Token::Bool(true), + Token::MapEnd, + Token::Map { len: Some(1) }, + Token::String("default"), + Token::I32(1), + Token::MapEnd, + Token::Map { len: Some(1) }, + Token::String("default"), + Token::F32(1.0), + Token::MapEnd, + Token::Map { len: Some(1) }, + Token::String("default"), + Token::String("1"), + Token::MapEnd, + Token::Map { len: Some(2) }, + Token::String("default_index"), + Token::U64(2), + Token::String("alternatives"), + Token::Seq { len: Some(2) }, + Token::I32(1), + Token::I32(2), + Token::SeqEnd, + Token::MapEnd, + Token::Map { len: Some(2) }, + Token::String("default_index"), + Token::U64(2), + Token::String("alternatives"), + Token::Seq { len: Some(2) }, + Token::F32(1.0), + Token::F32(2.0), + Token::SeqEnd, + Token::MapEnd, + Token::Map { len: Some(2) }, + Token::String("default_index"), + Token::U64(2), + Token::String("alternatives"), + Token::Seq { len: Some(2) }, + Token::String("1"), + Token::String("2"), + Token::SeqEnd, + Token::MapEnd, + Token::SeqEnd, + ]); } #[test] diff --git a/maa-cli/src/value/mod.rs b/maa-cli/src/value/mod.rs index edf78f9c..7584d6be 100644 --- a/maa-cli/src/value/mod.rs +++ b/maa-cli/src/value/mod.rs @@ -4,11 +4,10 @@ mod primate; pub use primate::MAAPrimate; mod input; -pub use input::MAAInput; - pub use std::collections::BTreeMap as Map; use std::io; +pub use input::MAAInput; use serde::{Deserialize, Serialize}; /// TODO: Zero-copy deserialization and reduce clone in init @@ -99,9 +98,10 @@ impl MAAValue { /// Initialize the value /// /// If the value is an primate value, do nothing. - /// If the value is an input value, try to get the value from user input and set it to the value. - /// If the value is an array or an object, initialize all the values in it recursively. - /// If the value is an optional value, initialize it only if all the dependencies are satisfied. + /// If the value is an input value, try to get the value from user input and set it to the + /// value. If the value is an array or an object, initialize all the values in it + /// recursively. If the value is an optional value, initialize it only if all the + /// dependencies are satisfied. /// /// # Errors /// @@ -182,8 +182,9 @@ impl MAAValue { let mut satisfied = true; // Check if all the dependencies are satisfied for (cond_key, expected) in conditions { - // If the dependency is not exist or the value is not equal to the expected values - // break the loop and mark status as unsatisfied + // If the dependency is not exist or the value is not equal to the + // expected values break the loop and mark + // status as unsatisfied if !initialized.get(&cond_key).is_some_and(|v| v == &expected) { satisfied = false; break; @@ -428,11 +429,10 @@ impl<'a> TryFromMAAValue<'a> for &str { #[cfg(test)] mod tests { - use crate::assert_matches; + use userinput::{BoolInput, Input, SelectD}; use super::*; - - use userinput::{BoolInput, Input, SelectD}; + use crate::assert_matches; impl MAAValue { pub fn merge(&self, other: &Self) -> Self { @@ -470,164 +470,158 @@ mod tests { object!("key1" => "value1", "key2" => "value2"), ); - serde_test::assert_de_tokens( - &obj, - &[ - Token::Map { len: Some(16) }, - Token::Str("array"), - Token::Seq { len: Some(2) }, - Token::I32(1), - Token::I32(2), - Token::SeqEnd, - Token::Str("bool"), - Token::Bool(true), - Token::Str("float"), - Token::F32(1.0), - Token::Str("int"), - Token::I32(1), - Token::Str("object"), - Token::Map { len: Some(1) }, - Token::Str("key"), - Token::Str("value"), - Token::MapEnd, - Token::Str("string"), - Token::Str("string"), - Token::Str("input_bool"), - Token::Map { len: Some(1) }, - Token::Str("default"), - Token::Bool(true), - Token::MapEnd, - Token::Str("input_int"), - Token::Map { len: Some(1) }, - Token::Str("default"), - Token::I32(1), - Token::MapEnd, - Token::Str("input_float"), - Token::Map { len: Some(1) }, - Token::Str("default"), - Token::F32(1.0), - Token::MapEnd, - Token::Str("input_string"), - Token::Map { len: Some(1) }, - Token::Str("default"), - Token::Str("string"), - Token::MapEnd, - Token::Str("select_int"), - Token::Map { len: Some(2) }, - Token::Str("alternatives"), - Token::Seq { len: Some(2) }, - Token::I32(1), - Token::I32(2), - Token::SeqEnd, - Token::Str("default_index"), - Token::U64(2), - Token::MapEnd, - Token::Str("select_float"), - Token::Map { len: Some(2) }, - Token::Str("alternatives"), - Token::Seq { len: Some(2) }, - Token::F32(1.0), - Token::F32(2.0), - Token::SeqEnd, - Token::Str("default_index"), - Token::U64(2), - Token::MapEnd, - Token::Str("select_string"), - Token::Map { len: Some(2) }, - Token::Str("alternatives"), - Token::Seq { len: Some(2) }, - Token::Str("string1"), - Token::Str("string2"), - Token::SeqEnd, - Token::Str("default_index"), - Token::U64(2), - Token::MapEnd, - Token::Str("optional"), - Token::Map { len: Some(2) }, - Token::Str("conditions"), - Token::Map { len: Some(1) }, - Token::Str("input_bool"), - Token::Bool(true), - Token::MapEnd, - Token::Str("default"), - Token::I32(1), - Token::MapEnd, - Token::Str("optional_no_satisfied"), - Token::Map { len: Some(2) }, - Token::Str("conditions"), - Token::Map { len: Some(1) }, - Token::Str("input_bool"), - Token::Bool(false), - Token::MapEnd, - Token::Str("default"), - Token::I32(1), - Token::MapEnd, - Token::Str("optional_object"), - Token::Map { len: Some(3) }, - Token::Str("conditions"), - Token::Map { len: Some(1) }, - Token::Str("input_bool"), - Token::Bool(true), - Token::MapEnd, - Token::Str("key1"), - Token::Str("value1"), - Token::Str("key2"), - Token::Str("value2"), - Token::MapEnd, - Token::MapEnd, - ], - ); + serde_test::assert_de_tokens(&obj, &[ + Token::Map { len: Some(16) }, + Token::Str("array"), + Token::Seq { len: Some(2) }, + Token::I32(1), + Token::I32(2), + Token::SeqEnd, + Token::Str("bool"), + Token::Bool(true), + Token::Str("float"), + Token::F32(1.0), + Token::Str("int"), + Token::I32(1), + Token::Str("object"), + Token::Map { len: Some(1) }, + Token::Str("key"), + Token::Str("value"), + Token::MapEnd, + Token::Str("string"), + Token::Str("string"), + Token::Str("input_bool"), + Token::Map { len: Some(1) }, + Token::Str("default"), + Token::Bool(true), + Token::MapEnd, + Token::Str("input_int"), + Token::Map { len: Some(1) }, + Token::Str("default"), + Token::I32(1), + Token::MapEnd, + Token::Str("input_float"), + Token::Map { len: Some(1) }, + Token::Str("default"), + Token::F32(1.0), + Token::MapEnd, + Token::Str("input_string"), + Token::Map { len: Some(1) }, + Token::Str("default"), + Token::Str("string"), + Token::MapEnd, + Token::Str("select_int"), + Token::Map { len: Some(2) }, + Token::Str("alternatives"), + Token::Seq { len: Some(2) }, + Token::I32(1), + Token::I32(2), + Token::SeqEnd, + Token::Str("default_index"), + Token::U64(2), + Token::MapEnd, + Token::Str("select_float"), + Token::Map { len: Some(2) }, + Token::Str("alternatives"), + Token::Seq { len: Some(2) }, + Token::F32(1.0), + Token::F32(2.0), + Token::SeqEnd, + Token::Str("default_index"), + Token::U64(2), + Token::MapEnd, + Token::Str("select_string"), + Token::Map { len: Some(2) }, + Token::Str("alternatives"), + Token::Seq { len: Some(2) }, + Token::Str("string1"), + Token::Str("string2"), + Token::SeqEnd, + Token::Str("default_index"), + Token::U64(2), + Token::MapEnd, + Token::Str("optional"), + Token::Map { len: Some(2) }, + Token::Str("conditions"), + Token::Map { len: Some(1) }, + Token::Str("input_bool"), + Token::Bool(true), + Token::MapEnd, + Token::Str("default"), + Token::I32(1), + Token::MapEnd, + Token::Str("optional_no_satisfied"), + Token::Map { len: Some(2) }, + Token::Str("conditions"), + Token::Map { len: Some(1) }, + Token::Str("input_bool"), + Token::Bool(false), + Token::MapEnd, + Token::Str("default"), + Token::I32(1), + Token::MapEnd, + Token::Str("optional_object"), + Token::Map { len: Some(3) }, + Token::Str("conditions"), + Token::Map { len: Some(1) }, + Token::Str("input_bool"), + Token::Bool(true), + Token::MapEnd, + Token::Str("key1"), + Token::Str("value1"), + Token::Str("key2"), + Token::Str("value2"), + Token::MapEnd, + Token::MapEnd, + ]); let obj = obj.init().unwrap(); - serde_test::assert_ser_tokens( - &obj, - &[ - Token::Map { len: Some(15) }, - Token::Str("array"), - Token::Seq { len: Some(2) }, - Token::I32(1), - Token::I32(2), - Token::SeqEnd, - Token::Str("bool"), - Token::Bool(true), - Token::Str("float"), - Token::F32(1.0), - Token::Str("input_bool"), - Token::Bool(true), - Token::Str("input_float"), - Token::F32(1.0), - Token::Str("input_int"), - Token::I32(1), - Token::Str("input_string"), - Token::Str("string"), - Token::Str("int"), - Token::I32(1), - Token::Str("object"), - Token::Map { len: Some(1) }, - Token::Str("key"), - Token::Str("value"), - Token::MapEnd, - Token::Str("optional"), - Token::I32(1), - Token::Str("optional_object"), - Token::Map { len: Some(2) }, - Token::Str("key1"), - Token::Str("value1"), - Token::Str("key2"), - Token::Str("value2"), - Token::MapEnd, - Token::Str("select_float"), - Token::F32(2.0), - Token::Str("select_int"), - Token::I32(2), - Token::Str("select_string"), - Token::Str("string2"), - Token::Str("string"), - Token::Str("string"), - Token::MapEnd, - ], - ); + serde_test::assert_ser_tokens(&obj, &[ + Token::Map { len: Some(15) }, + Token::Str("array"), + Token::Seq { len: Some(2) }, + Token::I32(1), + Token::I32(2), + Token::SeqEnd, + Token::Str("bool"), + Token::Bool(true), + Token::Str("float"), + Token::F32(1.0), + Token::Str("input_bool"), + Token::Bool(true), + Token::Str("input_float"), + Token::F32(1.0), + Token::Str("input_int"), + Token::I32(1), + Token::Str("input_string"), + Token::Str("string"), + Token::Str("int"), + Token::I32(1), + Token::Str("object"), + Token::Map { len: Some(1) }, + Token::Str("key"), + Token::Str("value"), + Token::MapEnd, + Token::Str("optional"), + Token::I32(1), + Token::Str("optional_object"), + Token::Map { len: Some(2) }, + Token::Str("key1"), + Token::Str("value1"), + Token::Str("key2"), + Token::Str("value2"), + Token::MapEnd, + Token::Str("select_float"), + Token::F32(2.0), + Token::Str("select_int"), + Token::I32(2), + Token::Str("select_string"), + Token::Str("string2"), + Token::Str("string"), + Token::Str("string"), + Token::MapEnd, + ]); serde_test::assert_ser_tokens_error( &object!( diff --git a/maa-cli/src/value/primate.rs b/maa-cli/src/value/primate.rs index 53de4ba2..90cb9079 100644 --- a/maa-cli/src/value/primate.rs +++ b/maa-cli/src/value/primate.rs @@ -1,7 +1,7 @@ -use super::MAAValue; - use serde::{Deserialize, Serialize}; +use super::MAAValue; + #[cfg_attr(test, derive(Debug))] #[derive(Deserialize, Clone, PartialEq)] #[serde(untagged)] @@ -19,6 +19,7 @@ impl MAAPrimate { _ => None, } } + pub(super) fn as_int(&self) -> Option { match self { Self::Int(v) => Some(*v), @@ -126,17 +127,14 @@ mod tests { MAAPrimate::String("".to_string()), ]; - assert_de_tokens( - &values, - &[ - Token::Seq { len: Some(4) }, - Token::Bool(true), - Token::I32(1), - Token::F32(1.0), - Token::Str(""), - Token::SeqEnd, - ], - ); + assert_de_tokens(&values, &[ + Token::Seq { len: Some(4) }, + Token::Bool(true), + Token::I32(1), + Token::F32(1.0), + Token::Str(""), + Token::SeqEnd, + ]); } #[test] diff --git a/maa-cli/src/value/userinput/bool_input.rs b/maa-cli/src/value/userinput/bool_input.rs index 11685e8f..523fb8b6 100644 --- a/maa-cli/src/value/userinput/bool_input.rs +++ b/maa-cli/src/value/userinput/bool_input.rs @@ -1,9 +1,9 @@ -use super::UserInput; - use std::io::{self, Write}; use serde::Deserialize; +use super::UserInput; + /// A struct that represents a user input that queries the user for boolean input. #[cfg_attr(test, derive(PartialEq))] #[derive(Deserialize, Debug, Clone)] @@ -75,12 +75,11 @@ impl UserInput for BoolInput { #[cfg(test)] mod tests { - use super::*; + use serde_test::{assert_de_tokens, Token}; + use super::*; use crate::assert_matches; - use serde_test::{assert_de_tokens, Token}; - #[test] fn serde() { let values = vec![ @@ -90,33 +89,30 @@ mod tests { BoolInput::new(None, None), ]; - assert_de_tokens( - &values, - &[ - Token::Seq { len: Some(4) }, - Token::Map { len: Some(2) }, - Token::Str("default"), - Token::Some, - Token::Bool(true), - Token::Str("description"), - Token::Some, - Token::Str("do something"), - Token::MapEnd, - Token::Map { len: Some(1) }, - Token::Str("default"), - Token::Some, - Token::Bool(false), - Token::MapEnd, - Token::Map { len: Some(1) }, - Token::Str("description"), - Token::Some, - Token::Str("do something"), - Token::MapEnd, - Token::Map { len: Some(0) }, - Token::MapEnd, - Token::SeqEnd, - ], - ); + assert_de_tokens(&values, &[ + Token::Seq { len: Some(4) }, + Token::Map { len: Some(2) }, + Token::Str("default"), + Token::Some, + Token::Bool(true), + Token::Str("description"), + Token::Some, + Token::Str("do something"), + Token::MapEnd, + Token::Map { len: Some(1) }, + Token::Str("default"), + Token::Some, + Token::Bool(false), + Token::MapEnd, + Token::Map { len: Some(1) }, + Token::Str("description"), + Token::Some, + Token::Str("do something"), + Token::MapEnd, + Token::Map { len: Some(0) }, + Token::MapEnd, + Token::SeqEnd, + ]); } #[test] @@ -129,13 +125,10 @@ mod tests { } if description == "do something" ); - assert_matches!( - BoolInput::new(Some(true), None), - BoolInput { - default: Some(true), - description: None, - } - ); + assert_matches!(BoolInput::new(Some(true), None), BoolInput { + default: Some(true), + description: None, + }); assert_matches!( BoolInput::new(None, Some("do something")), @@ -145,13 +138,10 @@ mod tests { } if description == "do something" ); - assert_matches!( - BoolInput::new(None, None), - BoolInput { - default: None, - description: None, - } - ); + assert_matches!(BoolInput::new(None, None), BoolInput { + default: None, + description: None, + }); } #[test] diff --git a/maa-cli/src/value/userinput/input.rs b/maa-cli/src/value/userinput/input.rs index fddc5151..c1a29c4b 100644 --- a/maa-cli/src/value/userinput/input.rs +++ b/maa-cli/src/value/userinput/input.rs @@ -1,5 +1,3 @@ -use super::UserInput; - use std::{ fmt::Display, io::{self, Write}, @@ -8,6 +6,8 @@ use std::{ use serde::Deserialize; +use super::UserInput; + #[cfg_attr(test, derive(PartialEq))] #[derive(Deserialize, Debug, Clone)] #[serde(deny_unknown_fields)] @@ -83,12 +83,11 @@ impl UserInput for Input { #[cfg(test)] mod tests { - use super::*; + use serde_test::{assert_de_tokens, Token}; + use super::*; use crate::assert_matches; - use serde_test::{assert_de_tokens, Token}; - #[test] fn serde() { let values: Vec> = vec![ @@ -98,33 +97,30 @@ mod tests { Input::new(None, None), ]; - assert_de_tokens( - &values, - &[ - Token::Seq { len: Some(4) }, - Token::Map { len: Some(2) }, - Token::Str("default"), - Token::Some, - Token::I32(0), - Token::Str("description"), - Token::Some, - Token::Str("how many medicine to use"), - Token::MapEnd, - Token::Map { len: Some(1) }, - Token::Str("default"), - Token::Some, - Token::I32(0), - Token::MapEnd, - Token::Map { len: Some(1) }, - Token::Str("description"), - Token::Some, - Token::Str("how many medicine to use"), - Token::MapEnd, - Token::Map { len: Some(0) }, - Token::MapEnd, - Token::SeqEnd, - ], - ); + assert_de_tokens(&values, &[ + Token::Seq { len: Some(4) }, + Token::Map { len: Some(2) }, + Token::Str("default"), + Token::Some, + Token::I32(0), + Token::Str("description"), + Token::Some, + Token::Str("how many medicine to use"), + Token::MapEnd, + Token::Map { len: Some(1) }, + Token::Str("default"), + Token::Some, + Token::I32(0), + Token::MapEnd, + Token::Map { len: Some(1) }, + Token::Str("description"), + Token::Some, + Token::Str("how many medicine to use"), + Token::MapEnd, + Token::Map { len: Some(0) }, + Token::MapEnd, + Token::SeqEnd, + ]); } #[test] @@ -143,20 +139,14 @@ mod tests { description: Some(s) } if s == "medicine to use", ); - assert_matches!( - Input::::new(Some(0), None::<&str>), - Input:: { - default: Some(0), - description: None, - }, - ); - assert_matches!( - Input::::new(None::, None::<&str>), - Input:: { - default: None, - description: None, - }, - ); + assert_matches!(Input::::new(Some(0), None::<&str>), Input:: { + default: Some(0), + description: None, + },); + assert_matches!(Input::::new(None::, None::<&str>), Input:: { + default: None, + description: None, + },); } #[test] diff --git a/maa-cli/src/value/userinput/mod.rs b/maa-cli/src/value/userinput/mod.rs index ac3d97cb..1ce5c434 100644 --- a/maa-cli/src/value/userinput/mod.rs +++ b/maa-cli/src/value/userinput/mod.rs @@ -97,7 +97,8 @@ pub trait UserInput: Sized { /// The caller will flush it when necessary. fn prompt(&self, writer: &mut impl Write) -> io::Result<()>; - /// Prompt user to re-input a value for this parameter when the input is empty and default value is not set. + /// Prompt user to re-input a value for this parameter when the input is empty and default value + /// is not set. /// /// Don't flush the writer after writing to it. /// The caller will flush it when necessary. diff --git a/maa-cli/src/value/userinput/select.rs b/maa-cli/src/value/userinput/select.rs index ecc8f612..0de80de2 100644 --- a/maa-cli/src/value/userinput/select.rs +++ b/maa-cli/src/value/userinput/select.rs @@ -1,5 +1,3 @@ -use super::UserInput; - use std::{ convert::Infallible, fmt::Display, @@ -10,6 +8,8 @@ use std::{ use anyhow::bail; use serde::Deserialize; +use super::UserInput; + #[cfg_attr(test, derive(PartialEq))] #[derive(Debug, Clone)] pub struct Select { @@ -61,7 +61,8 @@ impl Select { /// * `alternatives` - A list of alternatives for this parameter; /// * `default_index` - The 1-based index of the default value; /// * `description` - Description of this parameter, default to "one of the alternatives"; - /// * `allow_custom` - Allow custom input, if set to true and input is not a number, try to parse it; + /// * `allow_custom` - Allow custom input, if set to true and input is not a number, try to + /// parse it; /// /// # Examples /// @@ -69,10 +70,10 @@ impl Select { /// use crate::config::task::value::input::Select; /// /// let select = Select::::new( - /// vec!["CE-5", "CE-6"], - /// Some(2), - /// Some("a stage to fight"), - /// true, + /// vec!["CE-5", "CE-6"], + /// Some(2), + /// Some("a stage to fight"), + /// true, /// ); /// ``` /// @@ -298,8 +299,8 @@ impl From<&str> for ValueWithDesc { } impl Selectable for ValueWithDesc { - type Value = i32; type Error = ::Err; + type Value = i32; fn value(self) -> i32 { self.value() @@ -320,8 +321,8 @@ impl Display for ValueWithDesc { } impl Selectable for ValueWithDesc { - type Value = f32; type Error = ::Err; + type Value = f32; fn value(self) -> f32 { self.value() @@ -333,8 +334,8 @@ impl Selectable for ValueWithDesc { } impl Selectable for ValueWithDesc { - type Value = String; type Error = Infallible; + type Value = String; fn value(self) -> String { self.value() @@ -353,12 +354,11 @@ pub type SelectD = Select>; #[cfg(test)] mod tests { - use super::*; + use serde_test::{assert_de_tokens, Token}; + use super::*; use crate::assert_matches; - use serde_test::{assert_de_tokens, Token}; - // Use this function to get a Select with most fields set to Some. fn test_full() -> SelectD { SelectD::::new( @@ -382,45 +382,42 @@ mod tests { fn serde() { let values = [test_full(), test_none()]; - assert_de_tokens( - &values, - &[ - Token::Seq { len: Some(2) }, - Token::Map { len: Some(4) }, - Token::Str("alternatives"), - Token::Seq { len: Some(2) }, - Token::Map { len: Some(2) }, - Token::Str("value"), - Token::Str("CE-5"), - Token::Str("desc"), - Token::Str("LMB stage 5"), - Token::MapEnd, - Token::Map { len: Some(2) }, - Token::Str("value"), - Token::Str("CE-6"), - Token::Str("desc"), - Token::Str("LMB stage 6"), - Token::MapEnd, - Token::SeqEnd, - Token::Str("default_index"), - Token::Some, - Token::U64(2), - Token::Str("description"), - Token::Some, - Token::Str("a stage to fight"), - Token::Str("allow_custom"), - Token::Bool(true), - Token::MapEnd, - Token::Map { len: Some(1) }, - Token::Str("alternatives"), - Token::Seq { len: Some(2) }, - Token::Str("CE-5"), - Token::Str("CE-6"), - Token::SeqEnd, - Token::MapEnd, - Token::SeqEnd, - ], - ); + assert_de_tokens(&values, &[ + Token::Seq { len: Some(2) }, + Token::Map { len: Some(4) }, + Token::Str("alternatives"), + Token::Seq { len: Some(2) }, + Token::Map { len: Some(2) }, + Token::Str("value"), + Token::Str("CE-5"), + Token::Str("desc"), + Token::Str("LMB stage 5"), + Token::MapEnd, + Token::Map { len: Some(2) }, + Token::Str("value"), + Token::Str("CE-6"), + Token::Str("desc"), + Token::Str("LMB stage 6"), + Token::MapEnd, + Token::SeqEnd, + Token::Str("default_index"), + Token::Some, + Token::U64(2), + Token::Str("description"), + Token::Some, + Token::Str("a stage to fight"), + Token::Str("allow_custom"), + Token::Bool(true), + Token::MapEnd, + Token::Map { len: Some(1) }, + Token::Str("alternatives"), + Token::Seq { len: Some(2) }, + Token::Str("CE-5"), + Token::Str("CE-6"), + Token::SeqEnd, + Token::MapEnd, + Token::SeqEnd, + ]); } #[test] diff --git a/maa-dirs/src/lib.rs b/maa-dirs/src/lib.rs index d47c94a8..192f6352 100644 --- a/maa-dirs/src/lib.rs +++ b/maa-dirs/src/lib.rs @@ -163,8 +163,9 @@ impl Dirs { /// Try to find it in the directory relative to the executable file. /// First, try to find the MaaCore in the same directory as the executable file. /// Then, assume the executable file is in the `bin` directory, - /// try to find the MaaCore in the `lib` directory in the parent directory of the executable file. - /// If the executable is a symbolic link, will try to find the MaaCore both in the symbolic link and the link target. + /// try to find the MaaCore in the `lib` directory in the parent directory of the executable + /// file. If the executable is a symbolic link, will try to find the MaaCore both in the + /// symbolic link and the link target. pub fn find_library<'a>(&'a self, exe_path: &'a Path) -> Option> { if self.library().join(MAA_CORE_LIB).exists() { return Some(self.library().into()); @@ -238,8 +239,9 @@ impl Dirs { /// Try to find it in the directory relative to the executable file. /// First, try to find the resource directory in the same directory as the executable file. /// Then, assume the executable file is in the `bin` directory, - /// try to find the resource directory in the `share/maa` directory in the parent directory of the executable file. - /// If the executable is a symbolic link, will try to find the resource directory both in the symbolic link and the link target. + /// try to find the resource directory in the `share/maa` directory in the parent directory of + /// the executable file. If the executable is a symbolic link, will try to find the resource + /// directory both in the symbolic link and the link target. /// /// Additionally, if maa is compiled with `MAA_EXTRA_SHARE_NAME` environment variable, /// try to find the resource directory in the `share/$MAA_EXTRA_SHARE_NAME` directory. @@ -478,9 +480,10 @@ fn ensure_name(name: &str) -> &str { #[cfg(test)] mod tests { - use super::*; use std::env::{self, temp_dir}; + use super::*; + #[test] fn maa_lib_name() { #[cfg(target_os = "macos")] @@ -494,9 +497,10 @@ mod tests { } mod get_dir { - use super::*; use std::fs::{create_dir_all, remove_dir_all}; + use super::*; + fn project() -> Option { ProjectDirs::from("com", "loong", "maa") } @@ -641,8 +645,9 @@ mod tests { env::remove_var("MAA_DATA_DIR"); // Test find_library and find_resource at non-standard location (in a test directory) - // We need to use the provius dirs since the data directory is not at its standard location, - // to avoid find_library and find_resource returning the standard location. + // We need to use the provius dirs since the data directory is not at its standard + // location, to avoid find_library and find_resource returning the standard + // location. let test_root = temp_dir().join("maa-dirs-test-data-relative"); test_root.ensure_clean().unwrap(); let test_root = canonicalize(test_root).unwrap(); @@ -822,10 +827,9 @@ mod tests { std::fs::File::create(&test_file).unwrap(); - assert_eq!( - global_path([&test_dir1, &test_dir2], "test"), - vec![test_file.clone()] - ); + assert_eq!(global_path([&test_dir1, &test_dir2], "test"), vec![ + test_file.clone() + ]); assert_eq!( global_path([&test_dir1, &test_dir2], "not_exist"), Vec::::new() diff --git a/maa-sys/build.rs b/maa-sys/build.rs index 3d79d098..390bad01 100644 --- a/maa-sys/build.rs +++ b/maa-sys/build.rs @@ -1,10 +1,12 @@ #[cfg(not(feature = "runtime"))] fn static_link() { - use std::env::{ - consts::{DLL_PREFIX, DLL_SUFFIX}, - var_os, + use std::{ + env::{ + consts::{DLL_PREFIX, DLL_SUFFIX}, + var_os, + }, + path::PathBuf, }; - use std::path::PathBuf; let core_dir = var_os("MAA_CORE_DIR") .map(PathBuf::from) diff --git a/maa-sys/src/asst_type.rs b/maa-sys/src/asst_type.rs index 775d51b1..108e2641 100644 --- a/maa-sys/src/asst_type.rs +++ b/maa-sys/src/asst_type.rs @@ -75,7 +75,15 @@ pub enum TouchMode { impl TouchMode { pub const COUNT: usize = 4; - + pub const NAMES: [&'static str; Self::COUNT] = { + let mut i = 0; + let mut names = [""; Self::COUNT]; + while i < Self::COUNT { + names[i] = Self::VARIANTS[i].to_str(); + i += 1; + } + names + }; pub const VARIANTS: [TouchMode; Self::COUNT] = { let mut i = 0; let mut variants = [TouchMode::ADB; Self::COUNT]; @@ -96,16 +104,6 @@ impl TouchMode { } } - pub const NAMES: [&'static str; Self::COUNT] = { - let mut i = 0; - let mut names = [""; Self::COUNT]; - while i < Self::COUNT { - names[i] = Self::VARIANTS[i].to_str(); - i += 1; - } - names - }; - fn from_str_opt(s: &str) -> Option { Self::VARIANTS .iter() @@ -190,16 +188,16 @@ impl ToCString for TouchMode { #[cfg(test)] mod tests { - use super::*; - use TouchMode::*; + use super::*; + // #[cfg(not(feature = "runtime"))] // #[test] // fn apply_to() { // // Apply static options - // // We can't apply_to GPU OCR option because it requires a GPU which is not available in CI. - // StaticOptionKey::CpuOCR.apply_to(true).unwrap(); + // // We can't apply_to GPU OCR option because it requires a GPU which is not available in + // CI. StaticOptionKey::CpuOCR.apply_to(true).unwrap(); // // StaticOptionKey::GpuOCR.apply_to(1).unwrap(); // // use std::{env, path::Path}; @@ -278,10 +276,10 @@ mod tests { #[cfg(feature = "serde")] mod serde { - use super::*; - use serde_test::{assert_de_tokens, assert_de_tokens_error, Token}; + use super::*; + #[test] fn deserialize() { assert_de_tokens(&ADB, &[Token::Str("adb")]); diff --git a/maa-sys/src/lib.rs b/maa-sys/src/lib.rs index 9f666282..1b1edb3b 100644 --- a/maa-sys/src/lib.rs +++ b/maa-sys/src/lib.rs @@ -56,7 +56,7 @@ impl Assistant { } } - /*------------------------- Static Methods -------------------------*/ + /* ------------------------- Static Methods ------------------------- */ /// Set the user directory of the assistant. /// @@ -127,7 +127,7 @@ impl Assistant { Ok(()) } - /*------------------------ Instance Methods ------------------------*/ + /* ------------------------ Instance Methods ------------------------ */ //// Set the instance option of the assistant. pub fn set_instance_option( &self, @@ -185,14 +185,17 @@ impl Assistant { pub fn start(&self) -> Result<()> { handle_asst(unsafe { binding::AsstStart(self.handle) }) } + /// Stop the assistant. pub fn stop(&self) -> Result<()> { handle_asst(unsafe { binding::AsstStop(self.handle) }) } + /// Check if the assistant is running. pub fn running(&self) -> bool { unsafe { binding::AsstRunning(self.handle) != 0 } } + /// Check if the assistant is connected. pub fn connected(&self) -> bool { unsafe { binding::AsstConnected(self.handle) != 0 } diff --git a/maa-sys/src/task_type.rs b/maa-sys/src/task_type.rs index 73da0775..d5cbba95 100644 --- a/maa-sys/src/task_type.rs +++ b/maa-sys/src/task_type.rs @@ -22,7 +22,15 @@ pub enum TaskType { impl TaskType { pub const COUNT: usize = 16; - + pub const NAMES: [&'static str; Self::COUNT] = { + let mut i = 0; + let mut names = [""; Self::COUNT]; + while i < Self::COUNT { + names[i] = Self::VARIANTS[i].to_str(); + i += 1; + } + names + }; pub const VARIANTS: [Self; Self::COUNT] = { let mut i = 0; let mut variants = [Self::StartUp; Self::COUNT]; @@ -54,16 +62,6 @@ impl TaskType { } } - pub const NAMES: [&'static str; Self::COUNT] = { - let mut i = 0; - let mut names = [""; Self::COUNT]; - while i < Self::COUNT { - names[i] = Self::VARIANTS[i].to_str(); - i += 1; - } - names - }; - fn from_str_opt(s: &str) -> Option { Self::VARIANTS .iter() @@ -148,10 +146,10 @@ impl crate::ToCString for TaskType { #[cfg(test)] mod tests { - use super::*; - use TaskType::*; + use super::*; + #[test] fn parse() { assert_eq!("StartUp".parse(), Ok(StartUp)); @@ -184,23 +182,20 @@ mod tests { #[cfg(feature = "serde")] mod serde { - use super::*; - use serde_test::{assert_de_tokens, assert_de_tokens_error, Token}; + use super::*; + #[test] fn deserialize() { let types: [TaskType; 2] = [StartUp, CloseDown]; - assert_de_tokens( - &types, - &[ - Token::Seq { len: Some(2) }, - Token::Str("StartUp"), - Token::Str("CloseDown"), - Token::SeqEnd, - ], - ); + assert_de_tokens(&types, &[ + Token::Seq { len: Some(2) }, + Token::Str("StartUp"), + Token::Str("CloseDown"), + Token::SeqEnd, + ]); } #[test] @@ -245,10 +240,10 @@ mod tests { #[test] fn to_cstring() { - use crate::ToCString; - use std::ffi::CString; + use crate::ToCString; + assert_eq!( StartUp.to_cstring().unwrap(), CString::new("StartUp").unwrap(), diff --git a/maa-sys/src/to_cstring.rs b/maa-sys/src/to_cstring.rs index edff2f57..ba28d8c4 100644 --- a/maa-sys/src/to_cstring.rs +++ b/maa-sys/src/to_cstring.rs @@ -1,10 +1,10 @@ -use crate::{Error, Result}; - use std::{ ffi::CString, path::{Path, PathBuf}, }; +use crate::{Error, Result}; + /// A trait to convert a value to a UTF-8 encoded C string passed to MAA. pub trait ToCString { /// Convert the value of `self` to a UTF-8 encoded C string. @@ -50,7 +50,8 @@ impl ToCString for &Path { /// Implement `ToCString` by `as_ref` method. /// -/// `impl_to_cstring_by_as_ref!(ref_t, t1, t2, ...)` will implement `ToCString` for `t1`, `t2`, ... by `as_ref::` method. +/// `impl_to_cstring_by_as_ref!(ref_t, t1, t2, ...)` will implement `ToCString` for `t1`, `t2`, ... +/// by `as_ref::` method. #[macro_export] macro_rules! impl_to_cstring_by_as_ref { ($ref_t:ty, $($t:ty),*) => { @@ -77,7 +78,8 @@ impl ToCString for bool { /// Implement `ToCString` by `to_string` method. /// -/// `impl_to_cstring_by_to_string!(t1, t2, ...)` will implement `ToCString` for `t1`, `t2`, ... by `to_string` method. +/// `impl_to_cstring_by_to_string!(t1, t2, ...)` will implement `ToCString` for `t1`, `t2`, ... by +/// `to_string` method. #[macro_export] macro_rules! impl_to_cstring_by_to_string { ($($t:ty),*) => { diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 00000000..98357531 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,12 @@ +unstable_features = true + +comment_width = 100 +condense_wildcard_suffixes = true +format_code_in_doc_comments = true +format_macro_matchers = true +group_imports = "StdExternalCrate" +imports_granularity = "Crate" +overflow_delimited_expr = true +reorder_impl_items = true +use_field_init_shorthand = true +wrap_comments = true