From 2213d332782764ab19e20c867bafa75a8aab0b65 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Thu, 21 May 2026 19:22:27 +0800 Subject: Add path picker and PathChecker for CLI argument validation --- mingling/src/parser/picker/path/rule.rs | 218 ++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 mingling/src/parser/picker/path/rule.rs (limited to 'mingling/src/parser/picker/path/rule.rs') diff --git a/mingling/src/parser/picker/path/rule.rs b/mingling/src/parser/picker/path/rule.rs new file mode 100644 index 0000000..07df705 --- /dev/null +++ b/mingling/src/parser/picker/path/rule.rs @@ -0,0 +1,218 @@ +/// Path check rule +#[derive(Default)] +pub struct PathCheckRule { + pub exist_check: Option, + pub type_check: Option, +} + +/// Path existence check +pub enum PathExistCheck { + Exists, + NotExists, +} + +/// Path type check +pub struct PathTypeCheck { + /// Whether the path is allowed to be a file + pub allow_file: bool, + + /// Whether the path is allowed to be a directory + pub allow_dir: bool, + + /// Whether the path is allowed to be a symlink + pub allow_symlink: bool, +} + +impl PathCheckRule { + /// Creates a new `PathCheckRule` with default values + pub fn new() -> Self { + Self { + exist_check: None, + type_check: None, + } + } + + /// Allows the path to be a file + pub fn allow_file(self) -> Self { + match self.type_check { + Some(type_check) => Self { + type_check: Some(PathTypeCheck { + allow_file: true, + allow_dir: type_check.allow_dir, + allow_symlink: type_check.allow_symlink, + }), + ..self + }, + None => Self { + type_check: Some(PathTypeCheck { + allow_file: true, + allow_dir: false, + allow_symlink: false, + }), + ..self + }, + } + } + + /// Allows the path to be a directory + pub fn allow_dir(self) -> Self { + match self.type_check { + Some(type_check) => Self { + type_check: Some(PathTypeCheck { + allow_file: type_check.allow_file, + allow_dir: true, + allow_symlink: type_check.allow_symlink, + }), + ..self + }, + None => Self { + type_check: Some(PathTypeCheck { + allow_file: false, + allow_dir: true, + allow_symlink: false, + }), + ..self + }, + } + } + + /// Allows the path to be a symlink + pub fn allow_symlink(self) -> Self { + match self.type_check { + Some(type_check) => Self { + type_check: Some(PathTypeCheck { + allow_file: type_check.allow_file, + allow_dir: type_check.allow_dir, + allow_symlink: true, + }), + ..self + }, + None => Self { + type_check: Some(PathTypeCheck { + allow_file: false, + allow_dir: false, + allow_symlink: true, + }), + ..self + }, + } + } + + /// Denies the path from being a file + pub fn deny_file(self) -> Self { + match self.type_check { + Some(type_check) => Self { + type_check: Some(PathTypeCheck { + allow_file: false, + allow_dir: type_check.allow_dir, + allow_symlink: type_check.allow_symlink, + }), + ..self + }, + None => Self { + type_check: Some(PathTypeCheck { + allow_file: false, + allow_dir: true, + allow_symlink: true, + }), + ..self + }, + } + } + + /// Denies the path from being a directory + pub fn deny_dir(self) -> Self { + match self.type_check { + Some(type_check) => Self { + type_check: Some(PathTypeCheck { + allow_file: type_check.allow_file, + allow_dir: false, + allow_symlink: type_check.allow_symlink, + }), + ..self + }, + None => Self { + type_check: Some(PathTypeCheck { + allow_file: true, + allow_dir: false, + allow_symlink: true, + }), + ..self + }, + } + } + + /// Denies the path from being a symlink + pub fn deny_symlink(self) -> Self { + match self.type_check { + Some(type_check) => Self { + type_check: Some(PathTypeCheck { + allow_file: type_check.allow_file, + allow_dir: type_check.allow_dir, + allow_symlink: false, + }), + ..self + }, + None => Self { + type_check: Some(PathTypeCheck { + allow_file: true, + allow_dir: true, + allow_symlink: false, + }), + ..self + }, + } + } + + /// Requires the path to be a file (overrides type checks) + pub fn must_file(self) -> Self { + Self { + type_check: Some(PathTypeCheck { + allow_file: true, + allow_dir: false, + allow_symlink: false, + }), + ..self + } + } + + /// Requires the path to be a directory (overrides type checks) + pub fn must_dir(self) -> Self { + Self { + type_check: Some(PathTypeCheck { + allow_file: false, + allow_dir: true, + allow_symlink: false, + }), + ..self + } + } + + /// Requires the path to be a symlink (overrides type checks) + pub fn must_symlink(self) -> Self { + Self { + type_check: Some(PathTypeCheck { + allow_file: false, + allow_dir: false, + allow_symlink: true, + }), + ..self + } + } + + /// Requires the path to exist + pub fn must_exist(self) -> Self { + Self { + exist_check: Some(PathExistCheck::Exists), + ..self + } + } + + /// Requires the path to not exist + pub fn must_not_exist(self) -> Self { + Self { + exist_check: Some(PathExistCheck::NotExists), + ..self + } + } +} -- cgit