shell_sanitize/rule.rs
1use crate::error::RuleViolation;
2
3/// Result of a rule check: either pass or one or more violations.
4pub type RuleResult = Result<(), Vec<RuleViolation>>;
5
6/// A sanitization rule that inspects an input string and reports violations.
7///
8/// Implement this trait to create custom rules. Rules are composable via
9/// [`Sanitizer`](crate::Sanitizer).
10///
11/// # Example
12///
13/// ```
14/// use shell_sanitize::{Rule, RuleResult, RuleViolation};
15///
16/// struct NoSpacesRule;
17///
18/// impl Rule for NoSpacesRule {
19/// fn name(&self) -> &'static str { "no_spaces" }
20///
21/// fn check(&self, input: &str) -> RuleResult {
22/// let violations: Vec<_> = input
23/// .char_indices()
24/// .filter(|(_, c)| *c == ' ')
25/// .map(|(i, _)| RuleViolation::new(self.name(), "space character found")
26/// .at(i)
27/// .with_fragment(" "))
28/// .collect();
29/// if violations.is_empty() { Ok(()) } else { Err(violations) }
30/// }
31/// }
32/// ```
33pub trait Rule: Send + Sync {
34 /// A unique, human-readable identifier for this rule.
35 fn name(&self) -> &'static str;
36
37 /// Check the input and return violations, if any.
38 fn check(&self, input: &str) -> RuleResult;
39}
40
41impl Rule for Box<dyn Rule> {
42 fn name(&self) -> &'static str {
43 (**self).name()
44 }
45
46 fn check(&self, input: &str) -> RuleResult {
47 (**self).check(input)
48 }
49}