use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DCMode {
Standard = 1,
WindowClient = 2,
Desktop = 3,
}
impl fmt::Display for DCMode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DCMode::Standard => write!(f, "Standard"),
DCMode::WindowClient => write!(f, "WindowClient"),
DCMode::Desktop => write!(f, "Desktop"),
}
}
}
impl Default for DCMode {
fn default() -> Self {
DCMode::Standard
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct InitFlags {
pub init_pid: bool,
pub init_hwnd: bool,
pub init_handle: bool,
pub init_dc: bool,
}
impl InitFlags {
pub fn new() -> Self {
Self {
init_pid: true,
init_hwnd: true,
init_handle: true,
init_dc: true,
}
}
pub fn minimal() -> Self {
Self {
init_pid: true,
init_hwnd: false,
init_handle: false,
init_dc: false,
}
}
pub fn memory_only() -> Self {
Self {
init_pid: true,
init_hwnd: false,
init_handle: true,
init_dc: false,
}
}
pub fn gui_only() -> Self {
Self {
init_pid: true,
init_hwnd: true,
init_handle: false,
init_dc: true,
}
}
pub fn with_pid(mut self, value: bool) -> Self {
self.init_pid = value;
self
}
pub fn with_hwnd(mut self, value: bool) -> Self {
self.init_hwnd = value;
self
}
pub fn with_handle(mut self, value: bool) -> Self {
self.init_handle = value;
self
}
pub fn with_dc(mut self, value: bool) -> Self {
self.init_dc = value;
self
}
pub fn all() -> Self {
Self::new()
}
pub fn none() -> Self {
Self::minimal()
}
}
impl Default for InitFlags {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FilterRuleType {
Include,
Exclude,
}
#[derive(Debug, Clone)]
pub struct WindowFilter {
pub rules: Vec<FilterRule>,
}
#[derive(Debug, Clone)]
pub struct FilterRule {
pub rule_type: FilterRuleType,
pub criterion: FilterCriterion,
}
#[derive(Debug, Clone)]
pub enum FilterCriterion {
ByWindowTitle {
title_pattern: String,
case_sensitive: bool,
},
ByVisibility(bool), }
impl WindowFilter {
pub fn new() -> Self {
Self { rules: Vec::new() }
}
pub fn new_exclude_invisible() -> Self {
Self::new().exclude_invisible()
}
pub fn new_include_visible_only() -> Self {
Self::new().include_visible_only()
}
pub fn new_include_by_title(title_pattern: &str) -> Self {
Self::new().include_by_title(title_pattern)
}
pub fn include_by_title(mut self, title_pattern: &str) -> Self {
self.rules.push(FilterRule {
rule_type: FilterRuleType::Include,
criterion: FilterCriterion::ByWindowTitle {
title_pattern: title_pattern.to_string(),
case_sensitive: false,
},
});
self
}
pub fn include_by_exact_title(mut self, title: &str) -> Self {
self.rules.push(FilterRule {
rule_type: FilterRuleType::Include,
criterion: FilterCriterion::ByWindowTitle {
title_pattern: title.to_string(),
case_sensitive: true,
},
});
self
}
pub fn include_visible_only(mut self) -> Self {
self.rules.push(FilterRule {
rule_type: FilterRuleType::Include,
criterion: FilterCriterion::ByVisibility(true),
});
self
}
pub fn exclude_by_title(mut self, title_pattern: &str) -> Self {
self.rules.push(FilterRule {
rule_type: FilterRuleType::Exclude,
criterion: FilterCriterion::ByWindowTitle {
title_pattern: title_pattern.to_string(),
case_sensitive: false,
},
});
self
}
pub fn exclude_invisible(mut self) -> Self {
self.rules.push(FilterRule {
rule_type: FilterRuleType::Exclude,
criterion: FilterCriterion::ByVisibility(false),
});
self
}
pub fn is_empty(&self) -> bool {
self.rules.is_empty()
}
}
impl Default for WindowFilter {
fn default() -> Self {
Self::new()
}
}
pub struct ProcessConfigBuilder {
process_name: String,
dc_mode: DCMode,
window_filter: WindowFilter,
init_flags: InitFlags,
}
impl ProcessConfigBuilder {
pub fn new(process_name: &str) -> Self {
Self {
process_name: process_name.to_string(),
dc_mode: DCMode::default(),
window_filter: WindowFilter::new(),
init_flags: InitFlags::default(),
}
}
pub fn set_window_mode(mut self) -> Self {
self.dc_mode = DCMode::Standard;
self
}
pub fn set_window_client_mode(mut self) -> Self {
self.dc_mode = DCMode::WindowClient;
self
}
pub fn set_desktop_mode(mut self) -> Self {
self.dc_mode = DCMode::Desktop;
self
}
pub fn dc_mode(mut self, mode: DCMode) -> Self {
self.dc_mode = mode;
self
}
pub fn window_filter(mut self, filter: WindowFilter) -> Self {
self.window_filter = filter;
self
}
pub fn include_by_title(mut self, title_pattern: &str) -> Self {
self.window_filter = self.window_filter.include_by_title(title_pattern);
self
}
pub fn include_by_exact_title(mut self, title: &str) -> Self {
self.window_filter = self.window_filter.include_by_exact_title(title);
self
}
pub fn include_visible_only(mut self) -> Self {
self.window_filter = self.window_filter.include_visible_only();
self
}
pub fn exclude_by_title(mut self, title_pattern: &str) -> Self {
self.window_filter = self.window_filter.exclude_by_title(title_pattern);
self
}
pub fn exclude_invisible(mut self) -> Self {
self.window_filter = self.window_filter.exclude_invisible();
self
}
pub fn init_flags(mut self, flags: InitFlags) -> Self {
self.init_flags = flags;
self
}
pub fn build(self) -> ProcessConfig {
ProcessConfig {
process_name: self.process_name,
dc_mode: self.dc_mode,
window_filter: if self.window_filter.is_empty() {
None
} else {
Some(self.window_filter)
},
init_flags: self.init_flags,
}
}
}
#[derive(Debug, Clone)]
pub struct ProcessConfig {
pub process_name: String,
pub dc_mode: DCMode,
pub window_filter: Option<WindowFilter>,
pub init_flags: InitFlags,
}
impl ProcessConfig {
pub fn new(process_name: &str) -> Self {
Self {
process_name: process_name.to_string(),
dc_mode: DCMode::default(),
window_filter: None,
init_flags: InitFlags::default(),
}
}
pub fn builder(process_name: &str) -> ProcessConfigBuilder {
ProcessConfigBuilder::new(process_name)
}
}