async_aria2/
engine.rs

1use rand::{distributions::Alphanumeric, thread_rng, Rng};
2use std::{ffi::OsStr, process::Stdio, time::Duration};
3use tokio::{
4    io::{AsyncBufReadExt, BufReader},
5    process::{Child, Command},
6    time::timeout,
7};
8
9pub struct Engine {
10    pub token: String,
11    command: Command,
12    child: Option<Child>,
13}
14
15impl Engine {
16    pub fn new<I, S>(program: &str, args: I) -> Self
17    where
18        I: IntoIterator<Item = S>,
19        S: AsRef<OsStr>,
20    {
21        let secret: String = thread_rng().sample_iter(&Alphanumeric).take(8).collect();
22        let token = format!("token:{}", secret);
23        let mut command = Command::new(program);
24        command
25            .arg("--enable-rpc=true")
26            .arg(format!("--rpc-secret={}", secret))
27            .args(args)
28            .stdin(Stdio::null())
29            .stderr(Stdio::null())
30            .stdout(Stdio::piped());
31        Engine {
32            token,
33            command,
34            child: None,
35        }
36    }
37    pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Self {
38        self.command.arg(arg);
39        self
40    }
41    pub async fn start(&mut self) {
42        let mut child = self.command.spawn().unwrap();
43        let output = child.stdout.take().unwrap();
44        let reader = BufReader::new(output);
45        let mut lines = reader.lines();
46        let mut result = false;
47        timeout(Duration::from_secs(10), async {
48            while let Some(line) = lines.next_line().await.unwrap() {
49                if line.contains("[ERROR]") {
50                    panic!();
51                };
52                if line.contains("IPv4 RPC: listening on TCP port 6800") {
53                    result = true;
54                    break;
55                }
56            }
57        })
58        .await
59        .unwrap();
60        if result == false {
61            panic!();
62        }
63        self.child = Some(child);
64    }
65    pub fn stop(&mut self) {
66        if let Some(child) = &mut self.child {
67            child.kill().unwrap();
68        }
69    }
70}