use std::io;
use std::time::Duration;
use evalbox_sandbox::{Executor, Plan, SandboxId};
pub use evalbox_sandbox::Event;
use crate::error::Result;
pub struct Session {
executor: Executor,
}
impl Session {
pub fn new() -> io::Result<Self> {
Ok(Self {
executor: Executor::new()?,
})
}
pub fn spawn(&mut self, plan: Plan) -> Result<SandboxId> {
let id = self.executor.spawn(plan)?;
Ok(id)
}
pub fn spawn_cmd<I, S>(&mut self, cmd: I) -> Result<SandboxId>
where
I: IntoIterator<Item = S>,
S: Into<String>,
{
let plan = Plan::new(cmd);
self.spawn(plan)
}
pub fn poll(&mut self) -> io::Result<Vec<Event>> {
let mut events = Vec::new();
self.executor.poll(&mut events, Some(Duration::ZERO))?;
Ok(events)
}
pub fn poll_blocking(&mut self, timeout: Option<Duration>) -> io::Result<Vec<Event>> {
let mut events = Vec::new();
self.executor.poll(&mut events, timeout)?;
Ok(events)
}
pub fn active_count(&self) -> usize {
self.executor.active_count()
}
pub fn is_empty(&self) -> bool {
self.active_count() == 0
}
pub fn kill(&mut self, id: SandboxId) -> io::Result<()> {
self.executor.kill(id)
}
pub fn write_stdin(&mut self, id: SandboxId, data: &[u8]) -> io::Result<usize> {
self.executor.write_stdin(id, data)
}
pub fn close_stdin(&mut self, id: SandboxId) -> io::Result<()> {
self.executor.close_stdin(id)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_session_new() {
let session = Session::new();
assert!(session.is_ok());
}
#[test]
fn test_session_empty_initially() {
let session = Session::new().unwrap();
assert!(session.is_empty());
assert_eq!(session.active_count(), 0);
}
}