use std::fmt;
use std::path::PathBuf;
use std::time::Instant;
use heim_common::prelude::*;
use heim_common::units::Time;
use crate::{sys, Pid, ProcessResult};
mod command;
mod cpu_times;
mod cpu_usage;
mod memory;
mod status;
pub use self::command::{Command, CommandIter};
pub use self::cpu_times::CpuTime;
pub use self::cpu_usage::CpuUsage;
pub use self::memory::Memory;
pub use self::status::Status;
#[derive(Eq, PartialEq, Hash)]
pub struct Process(sys::Process);
wrap!(Process, sys::Process);
impl Process {
pub fn pid(&self) -> Pid {
self.as_ref().pid()
}
pub fn parent_pid(&self) -> impl Future<Output = ProcessResult<Pid>> {
self.as_ref().parent_pid()
}
pub fn parent(&self) -> impl Future<Output = ProcessResult<Process>> {
self.parent_pid().and_then(get)
}
pub fn name(&self) -> impl Future<Output = ProcessResult<String>> {
self.as_ref().name()
}
pub fn exe(&self) -> impl Future<Output = ProcessResult<PathBuf>> {
self.as_ref().exe()
}
pub fn command(&self) -> impl Future<Output = ProcessResult<Command>> {
self.as_ref().command().map_ok(Into::into)
}
pub fn cwd(&self) -> impl Future<Output = ProcessResult<PathBuf>> {
self.as_ref().cwd()
}
pub fn status(&self) -> impl Future<Output = ProcessResult<Status>> {
self.as_ref().status()
}
pub fn create_time(&self) -> impl Future<Output = ProcessResult<Time>> {
self.as_ref().create_time()
}
pub fn cpu_time(&self) -> impl Future<Output = ProcessResult<CpuTime>> {
self.as_ref().cpu_time().map_ok(Into::into)
}
pub fn cpu_usage(&self) -> impl Future<Output = ProcessResult<CpuUsage>> {
self.cpu_time().and_then(|time| {
heim_cpu::logical_count()
.map_err(Into::into)
.map_ok(move |count| CpuUsage {
cpu_count: count,
cpu_time: time,
at: Instant::now(),
})
})
}
pub fn memory(&self) -> impl Future<Output = ProcessResult<Memory>> {
self.as_ref().memory().map_ok(Into::into)
}
pub fn is_running(&self) -> impl Future<Output = ProcessResult<bool>> {
self.as_ref().is_running()
}
pub fn suspend(&self) -> impl Future<Output = ProcessResult<()>> {
self.0.suspend()
}
pub fn resume(&self) -> impl Future<Output = ProcessResult<()>> {
self.0.resume()
}
pub fn terminate(&self) -> impl Future<Output = ProcessResult<()>> {
self.0.terminate()
}
pub fn kill(&self) -> impl Future<Output = ProcessResult<()>> {
self.0.kill()
}
}
impl fmt::Debug for Process {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Process").field("pid", &self.pid()).finish()
}
}
pub fn processes() -> impl Stream<Item = ProcessResult<Process>> {
sys::processes().map_ok(Into::into)
}
pub fn get(pid: Pid) -> impl Future<Output = ProcessResult<Process>> {
sys::get(pid).map_ok(Into::into)
}
pub fn current() -> impl Future<Output = ProcessResult<Process>> {
sys::current().map_ok(Into::into)
}