frc/src/chromedriver.rs

67 lines
1.9 KiB
Rust

use std::{
fmt,
io::{BufRead, BufReader},
process::{Child, Command, Stdio},
};
use sysinfo::{Pid, ProcessRefreshKind, RefreshKind, System, SystemExt};
#[derive(Debug, Clone)]
struct AddrInUse;
impl fmt::Display for AddrInUse {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "address is in use")
}
}
pub struct Driver {
child: Child,
}
impl Driver {
pub fn new() -> Result<Self, anyhow::Error> {
let mut child = Command::new("chromedriver")
.stdout(Stdio::piped())
.arg("--port=6444")
.spawn()?;
let child_id = child.id();
let mut child_out = BufReader::new(child.stdout.as_mut().unwrap());
let mut line = String::new();
let mut sys_info = System::new_with_specifics(
RefreshKind::new().with_processes(ProcessRefreshKind::new()),
);
// Wait for it to say Chromedriver started successfully
loop {
child_out.read_line(&mut line).unwrap();
if line.contains("ChromeDriver was started successfully.") {
break;
}
if line.contains("bind() failed: Address already in use") || line.contains("Exiting...")
{
return Err(anyhow::anyhow!(line));
}
// Check if chromedriver has exited
sys_info.refresh_all();
if let None = sys_info.process(Pid::from(child_id.clone() as i32)) {
let status_code = child.wait()?;
println!("{}", status_code.code().unwrap());
return Err(anyhow::anyhow!(
"chromedriver exited with status code {}",
status_code.code().unwrap_or(1337),
));
}
}
println!("chromedriver started");
Ok(Self { child })
}
pub fn exit(&mut self) -> Result<(), anyhow::Error> {
self.child.kill()?;
Ok(())
}
}