1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
use tokio::io::{AsyncBufReadExt, BufReader}; // 确保导入所需的trait
use tokio::process::Command;
/// ADBCmd allows you to execute adb commands asynchronously.
pub struct ADBCmd {}
impl ADBCmd {
pub fn new() -> ADBCmd {
ADBCmd {}
}
// run_async runs the given adb command asynchronously.
/// ```no_run
/// use std::process::Command;
///
/// use ADB::cmd::ADBCmd;
///
/// let adb_cmd = ADBCmd::new();
///
/// db_cmd.run_async(vec!["devices".to_string()], |line| {
/// println!("{}", line);
/// line
/// }).await;
/// ```
pub async fn run_async<F>(&self, args: Vec<String>, mut fnc: F)
where
F: FnMut(String) -> String + 'static,
{
let mut cmd = Command::new("adb")
.args(args)
.stdout(std::process::Stdio::piped()) // 将标准输出重定向到管道
.spawn() // 启动子进程
.expect("failed to execute command");
if let Some(stdout) = cmd.stdout.take() {
let reader = BufReader::new(stdout);
let mut lines = reader.lines();
while let Ok(Some(line)) = lines.next_line().await {
let _result = fnc(line);
// 这里你可以直接使用 `result`,或者根据需要做进一步的处理
}
}
}
// run runs the given adb command synchronously.
/// ```no_run
/// use std::process::Command;
///
/// use ADB::cmd::ADBCmd;
///
/// let adb_cmd = ADBCmd::new();
///
/// let result = adb_cmd.run(vec!["devices".to_string()]);
/// ```
pub fn run(&self, args: Vec<String>) -> Result<String, String> {
let output = std::process::Command::new("adb").args(args).output();
match output {
Ok(child) => {
if child.status.success() {
let stdout = String::from_utf8_lossy(&child.stdout).to_string();
Ok(stdout)
} else {
let stderr = String::from_utf8_lossy(&child.stderr).to_string();
Err(stderr)
}
}
Err(err) => {
let err_str = format!("Failed to execute Adb command: {}", err) as String;
Err(err_str)
}
}
}
}