use std::fmt;
use crate::traits::ProcessStore;
#[derive(Debug, Clone)]
pub enum ProcEvent {
Fork {
child_pid: u32,
parent_pid: u32,
timestamp_ns: u64,
},
Exec { pid: u32, timestamp_ns: u64 },
Exit { pid: u32 },
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[must_use = "call .remove(&store) after processing related events, or the process stays in store until TTL expires"]
pub struct ExitedProcess {
pub pid: u32,
}
impl ExitedProcess {
pub fn pid(&self) -> u32 {
self.pid
}
pub fn remove<S: ProcessStore>(self, store: &S) {
store.remove_process(self.pid);
}
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct ProcessLink {
pid: u32,
comm: String,
cmd: String,
user: String,
}
impl ProcessLink {
pub fn new(pid: u32, comm: String, cmd: String, user: String) -> Self {
Self {
pid,
comm,
cmd,
user,
}
}
pub fn pid(&self) -> u32 {
self.pid
}
pub fn comm(&self) -> &str {
&self.comm
}
pub fn cmd(&self) -> &str {
&self.cmd
}
pub fn user(&self) -> &str {
&self.user
}
}
impl fmt::Display for ProcessLink {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}|{}|{}", self.pid, self.cmd, self.user)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn process_link_display_format() {
let link = ProcessLink::new(42, "bash".into(), "bash".into(), "root".into());
assert_eq!(link.to_string(), "42|bash|root");
}
#[test]
fn process_link_clone() {
let link = ProcessLink::new(1, "init".into(), "init".into(), "root".into());
let link2 = link.clone();
assert_eq!(link.pid(), link2.pid());
assert_eq!(link.cmd(), link2.cmd());
assert_eq!(link.user(), link2.user());
}
#[test]
fn proc_event_clone() {
let e = ProcEvent::Fork {
child_pid: 100,
parent_pid: 1,
timestamp_ns: 42,
};
let e2 = e.clone();
match e2 {
ProcEvent::Fork {
child_pid,
parent_pid,
timestamp_ns,
} => {
assert_eq!(child_pid, 100);
assert_eq!(parent_pid, 1);
assert_eq!(timestamp_ns, 42);
}
_ => panic!("expected Fork"),
}
}
}