accessibility_rs/engine/rules/
rule.rs

1use crate::engine::rules::techniques::Techniques;
2use crate::engine::rules::wcag_base::{Guideline, IssueType, Principle};
3use accessibility_scraper::ElementRef;
4
5/// the validation response
6#[derive(Default, Debug)]
7pub struct Validation {
8    /// is valid
9    pub valid: bool,
10    /// the sub-technique
11    pub id: &'static str,
12    /// elements that match the issue
13    pub elements: Vec<String>,
14    /// the message of the error
15    pub message: String,
16}
17
18impl Validation {
19    /// helper to create validation
20    pub fn new(valid: bool, id: &'static str, elements: Vec<String>, message: String) -> Self {
21        Self {
22            valid,
23            id,
24            elements,
25            message,
26        }
27    }
28    /// basic validation
29    pub fn new_issue(valid: bool, id: &'static str) -> Self {
30        Self {
31            valid,
32            id,
33            ..Default::default()
34        }
35    }
36
37    /// basic validation with custom message
38    pub fn new_custom_issue(valid: bool, id: &'static str, message: String) -> Self {
39        Self {
40            valid,
41            id,
42            message,
43            ..Default::default()
44        }
45    }
46}
47
48#[derive(Debug, Clone)]
49/// techniques for a rule
50pub enum Technique {
51    /// a single technique
52    Single(Techniques),
53    /// multiple techniques
54    Multi(Vec<Techniques>),
55}
56
57impl Technique {
58    /// technique(s) into string
59    pub fn into_str(&self) -> String {
60        match self {
61            Technique::Multi(tech) => tech
62                .iter()
63                .map(|x| x.as_str())
64                .collect::<Vec<_>>()
65                .join(",")
66                .into(),
67            Technique::Single(tech) => tech.as_str().into(),
68        }
69    }
70}
71
72impl From<Techniques> for Technique {
73    fn from(t: Techniques) -> Self {
74        Technique::Single(t)
75    }
76}
77
78impl From<Vec<Techniques>> for Technique {
79    fn from(t: Vec<Techniques>) -> Self {
80        Technique::Multi(t)
81    }
82}
83
84/// validation rule(s) that should be handled
85pub enum RuleValidation {
86    /// a single rule for validation
87    Single(Validation),
88    /// multiple validation rules applied
89    Multi(Vec<Validation>),
90}
91
92impl From<Validation> for RuleValidation {
93    fn from(t: Validation) -> Self {
94        RuleValidation::Single(t)
95    }
96}
97
98impl From<Vec<Validation>> for RuleValidation {
99    fn from(t: Vec<Validation>) -> Self {
100        RuleValidation::Multi(t)
101    }
102}
103
104type ValidateFn =
105    fn(&Vec<(ElementRef<'_>, Option<taffy::NodeId>)>, &crate::Auditor<'_>) -> RuleValidation;
106
107/// the rule validation method that should be performed.
108#[derive(Debug)]
109pub struct Rule {
110    /// the message id of the rule to point to the locale
111    pub rule_id: Technique,
112    /// the type of rule
113    pub issue_type: IssueType,
114    /// validate a test returns (valid, rule, selectors)
115    pub validate: ValidateFn,
116    /// the principle type
117    pub principle: Principle,
118    /// the guideline to follow
119    pub guideline: Guideline,
120    /// the success criteria
121    pub success_criteria: &'static str,
122}
123
124impl Rule {
125    /// a new rule type
126    pub fn new(
127        rule_id: Technique,
128        issue_type: IssueType,
129        principle: Principle,
130        guideline: Guideline,
131        success_criteria: &'static str,
132        validate: ValidateFn,
133    ) -> Rule {
134        Rule {
135            rule_id,
136            issue_type,
137            guideline,
138            principle,
139            success_criteria,
140            validate,
141        }
142    }
143}