aboutsummaryrefslogtreecommitdiff
path: root/core/src/service/cli_addition
diff options
context:
space:
mode:
author1992414357@qq.com <1992414357@qq.com>2025-06-09 01:44:36 +0800
committer1992414357@qq.com <1992414357@qq.com>2025-06-09 01:44:36 +0800
commit49192dbb98e0ab1f2a66b4786fac86d63f69be64 (patch)
tree7cdf27c7cab5fb6b1aabc2ac7c44b7b492558945 /core/src/service/cli_addition
parentc9dbba0d288becb7f05cebe526be25c76e5a850a (diff)
重构所有部分
Diffstat (limited to 'core/src/service/cli_addition')
-rw-r--r--core/src/service/cli_addition/mod.rs2
-rw-r--r--core/src/service/cli_addition/runtime_consoles.rs60
-rw-r--r--core/src/service/cli_addition/utils.rs58
3 files changed, 120 insertions, 0 deletions
diff --git a/core/src/service/cli_addition/mod.rs b/core/src/service/cli_addition/mod.rs
new file mode 100644
index 0000000..ced68da
--- /dev/null
+++ b/core/src/service/cli_addition/mod.rs
@@ -0,0 +1,2 @@
+pub mod runtime_consoles;
+mod utils;
diff --git a/core/src/service/cli_addition/runtime_consoles.rs b/core/src/service/cli_addition/runtime_consoles.rs
new file mode 100644
index 0000000..76ff20c
--- /dev/null
+++ b/core/src/service/cli_addition/runtime_consoles.rs
@@ -0,0 +1,60 @@
+use crate::service::cli_addition::utils::read_cli;
+use clap::{Command, FromArgMatches};
+use std::sync::{Arc, Mutex};
+use tokio::{join, spawn};
+use crate::service::service_runner::NoGamepadsService;
+
+pub struct RuntimeConsole<PadService, Cmd>
+where Cmd: FromArgMatches {
+ command: Command,
+ prefix: String,
+ service: Arc<Mutex<PadService>>,
+ process_command: fn(Arc<Mutex<PadService>>, Cmd),
+}
+
+impl<PadService: Send + 'static, Cmd: FromArgMatches + 'static> RuntimeConsole<PadService, Cmd> {
+ pub fn build(command: Command,
+ prefix: String,
+ service: Arc<Mutex<PadService>>,
+ process_command: fn(Arc<Mutex<PadService>>, Cmd),
+ ) -> RuntimeConsole<PadService, Cmd> {
+ RuntimeConsole { command, prefix, service, process_command }
+ }
+
+ pub fn build_entry(self) -> NoGamepadsService {
+ let arc = Arc::new(self);
+
+ let entry = async move {
+ let console_main = spawn({
+ let console = Arc::clone(&arc);
+ async move {
+ Self::console_main(console).await
+ }
+ });
+
+ // Join
+ let _ = join!(console_main);
+ };
+
+ Box::pin(entry)
+ }
+
+ async fn console_main(self: Arc<RuntimeConsole<PadService, Cmd>>) {
+ let prefix_uppercase = self.prefix.to_uppercase();
+ let prefix_lowercase = self.prefix.to_lowercase();
+
+ loop {
+ let option : Option<Cmd> = read_cli(
+ format!("{}> ", prefix_uppercase),
+ &prefix_lowercase,
+ self.command.clone()
+ ).await;
+ match option {
+ None => {}
+ Some(cmd) => {
+ (self.process_command)(Arc::clone(&self.service), cmd);
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/core/src/service/cli_addition/utils.rs b/core/src/service/cli_addition/utils.rs
new file mode 100644
index 0000000..05969a5
--- /dev/null
+++ b/core/src/service/cli_addition/utils.rs
@@ -0,0 +1,58 @@
+use clap::{Command, FromArgMatches};
+use clap::ColorChoice::Auto;
+use tokio::io::{AsyncBufReadExt, AsyncWriteExt};
+
+pub async fn read_cli<Cmd>(prefix: String, entry: &String, cmd: Command) -> Option<Cmd>
+where Cmd: FromArgMatches {
+ let input: String = {
+ let mut buffer = String::new();
+ let mut stdin = tokio::io::BufReader::new(tokio::io::stdin());
+ let mut stdout = tokio::io::stdout();
+
+ stdout.write_all(prefix.as_bytes()).await.ok().unwrap();
+ stdout.flush().await.ok().unwrap();
+
+ stdin.read_line(&mut buffer).await.ok().unwrap();
+ buffer.trim().to_string()
+ };
+
+ process_debug_cli(entry, input, cmd).await
+}
+
+async fn process_debug_cli<Cmd>(entry: &String, input: String, cmd: Command) -> Option<Cmd>
+where Cmd: FromArgMatches {
+ if input.trim().is_empty() {
+ return None;
+ }
+
+ let cmd = cmd
+ .color(Auto)
+ .help_template(
+ "{subcommands}{options}"
+ )
+ .disable_help_flag(true)
+ .disable_version_flag(true);
+
+ let args = shell_words::split(input.as_str()).unwrap_or_else(|_e| {
+ ["".to_string()].to_vec()
+ });
+
+ let full_args = std::iter::once(entry.into()).chain(args);
+
+ match cmd.try_get_matches_from(full_args) {
+ Ok(matches) => {
+ match Cmd::from_arg_matches(&matches) {
+ Ok(cmd) => {
+ Some(cmd)
+ }
+ Err(_err) => {
+ None
+ }
+ }
+ }
+ Err(err) => {
+ println!("{}", err);
+ None
+ }
+ }
+} \ No newline at end of file