isabelle_client/
server.rs1use std::{
2 io::{self, BufRead, BufReader},
3 process::{Command, ExitStatus, Stdio},
4};
5
6pub struct IsabelleServer {
8 handle: Option<std::process::Child>,
9 port: u32,
10 passwd: String,
11 name: String,
12}
13
14impl IsabelleServer {
15 pub fn port(&self) -> u32 {
17 self.port
18 }
19
20 pub fn password(&self) -> &str {
22 &self.passwd
23 }
24
25 pub fn name(&self) -> &str {
26 &self.name
27 }
28
29 pub fn exit(&mut self) -> io::Result<()> {
31 exit(&self.name)?;
32
33 if let Some(mut handle) = self.handle.take() {
35 if let Ok(None) = handle.try_wait() {
36 handle.kill()?;
37 }
38 }
39
40 Ok(())
41 }
42}
43
44pub fn run_server(name: Option<&str>) -> io::Result<IsabelleServer> {
69 let name = name.unwrap_or("isabelle").to_string();
70 let mut handle = Command::new("isabelle")
71 .arg("server")
72 .arg("-n")
73 .arg(&name)
74 .stdout(Stdio::piped())
75 .spawn()?;
76
77 let stdout = handle.stdout.take().unwrap();
78
79 let mut stdout_buf = vec![];
80 let newline = b'\n';
81 BufReader::new(stdout).read_until(newline, &mut stdout_buf)?;
83
84 let stdout_str = String::from_utf8(stdout_buf)
85 .unwrap()
86 .replace('\\', "")
87 .trim()
88 .to_string();
89
90 let addr_re = regex::Regex::new(r#".* = .*:(.*) \(password "(.*)"\)"#).unwrap();
91 let caps = addr_re.captures(&stdout_str).unwrap();
92
93 let port = caps.get(1).unwrap().as_str().parse::<u32>().unwrap();
94 let passwd = caps.get(2).unwrap().as_str().to_owned();
95
96 let server = if handle.try_wait()?.is_none() {
97 IsabelleServer {
98 handle: Some(handle),
99 port,
100 passwd,
101 name,
102 }
103 } else {
104 IsabelleServer {
105 handle: None,
106 port,
107 passwd,
108 name,
109 }
110 };
111
112 Ok(server)
113}
114
115pub fn exit(name: &str) -> io::Result<ExitStatus> {
117 let mut child = Command::new("isabelle")
118 .arg("server")
119 .arg("-n")
120 .arg(name)
121 .arg("-x")
122 .spawn()?;
123 child.wait()
124}
125
126mod tests {
127
128 #![allow(unused_imports)] use super::run_server;
130 use serial_test::serial;
131
132 #[test]
133 #[serial]
134 fn test_run_server() {
135 let mut server = run_server(Some("test")).unwrap();
136 assert!(server.port > 0);
137 assert!(!server.passwd.is_empty());
138 server.exit().unwrap();
139 }
140}