use std::ffi::{OsStr, OsString};
use std::path::{Path, PathBuf};
use crate::ProcessIdentity;
#[derive(Debug, Clone, Default)]
pub struct ResourceBatch {
files: Vec<PathBuf>,
processes: Vec<ProcessIdentity>,
services: Vec<OsString>,
}
impl ResourceBatch {
#[must_use]
pub const fn new() -> Self {
Self {
files: Vec::new(),
processes: Vec::new(),
services: Vec::new(),
}
}
#[must_use]
pub fn file(mut self, file: impl Into<PathBuf>) -> Self {
self.files.push(file.into());
self
}
#[must_use]
pub fn process(mut self, process: ProcessIdentity) -> Self {
self.processes.push(process);
self
}
#[must_use]
pub fn service(mut self, service: impl Into<OsString>) -> Self {
self.services.push(service.into());
self
}
pub fn add_file(&mut self, file: impl Into<PathBuf>) -> &mut Self {
self.files.push(file.into());
self
}
pub fn add_process(&mut self, process: ProcessIdentity) -> &mut Self {
self.processes.push(process);
self
}
pub fn add_service(&mut self, service: impl Into<OsString>) -> &mut Self {
self.services.push(service.into());
self
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.files.is_empty() && self.processes.is_empty() && self.services.is_empty()
}
#[must_use]
pub fn len(&self) -> usize {
self.files.len() + self.processes.len() + self.services.len()
}
pub(crate) fn files(&self) -> impl Iterator<Item = &Path> {
self.files.iter().map(PathBuf::as_path)
}
pub(crate) fn processes(&self) -> &[ProcessIdentity] {
&self.processes
}
pub(crate) fn services(&self) -> impl Iterator<Item = &OsStr> {
self.services.iter().map(OsString::as_os_str)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn builder_and_mutating_forms_cover_every_resource_kind() {
let process = ProcessIdentity::from_raw_parts(1, 2).unwrap();
let resources = ResourceBatch::new()
.file("one.txt")
.process(process)
.service("EventLog");
assert_eq!(resources.len(), 3);
assert!(!resources.is_empty());
assert_eq!(
resources.files().collect::<Vec<_>>(),
[Path::new("one.txt")]
);
assert_eq!(resources.processes(), &[process]);
assert_eq!(
resources.services().collect::<Vec<_>>(),
[OsStr::new("EventLog")]
);
let mut resources = ResourceBatch::default();
assert!(resources.is_empty());
resources
.add_file("two.txt")
.add_process(process)
.add_service("Schedule");
assert_eq!(resources.len(), 3);
}
}