#![warn(missing_docs)]
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate rust_i18n;
#[cfg(feature = "spider")]
pub use spider;
pub mod engine;
pub mod i18n;
pub use accessibility_scraper;
pub use accessibility_scraper::fast_html5ever;
pub use accessibility_scraper::Html;
pub use accessibility_scraper::ElementRef;
pub use crate::engine::audit::auditor::Auditor;
pub use crate::engine::issue::Issue;
i18n!("locales", fallback = "en");
#[derive(Default)]
pub enum Conformance {
#[default]
WCAGAAA,
}
#[derive(Default)]
#[cfg(feature = "tokio")]
pub struct AuditConfig {
pub html: String,
pub css: String,
pub bounding_box: bool,
pub locale: String,
pub conformance: Conformance,
#[cfg(feature = "spider")]
pub url: String,
}
#[derive(Default)]
#[cfg(not(feature = "tokio"))]
pub struct AuditConfig<'a> {
pub html: &'a str,
pub css: &'a str,
pub bounding_box: bool,
pub locale: &'a str,
pub conformance: Conformance,
#[cfg(feature = "spider")]
pub url: &'a str,
}
#[cfg(not(feature = "tokio"))]
impl<'a> AuditConfig<'a> {
pub fn new(html: &'a str, css: &'a str, bounding_box: bool, locale: &'a str) -> Self {
AuditConfig {
html: html.into(),
css: css.into(),
bounding_box,
locale: locale.into(),
..Default::default()
}
}
pub fn basic(html: &'a str) -> Self {
AuditConfig {
html: html.into(),
..Default::default()
}
}
#[cfg(feature = "spider")]
pub fn new_website(url: &'a str, css: &'a str, bounding_box: bool, locale: &'a str) -> Self {
AuditConfig {
url: url.into(),
css: css.into(),
bounding_box,
locale: locale.into(),
..Default::default()
}
}
#[cfg(not(feature = "spider"))]
pub fn new_website(
_url: &'a str,
_css: &'a str,
_bounding_box: bool,
_locale: &'a str,
) -> Self {
AuditConfig::default()
}
}
#[cfg(feature = "tokio")]
impl AuditConfig {
pub fn new(html: &str, css: &str, bounding_box: bool, locale: &str) -> Self {
AuditConfig {
html: html.into(),
css: css.into(),
bounding_box,
locale: locale.into(),
..Default::default()
}
}
pub fn basic(html: &str) -> Self {
AuditConfig {
html: html.into(),
..Default::default()
}
}
#[cfg(feature = "spider")]
pub fn new_website(url: &str, css: &str, bounding_box: bool, locale: &str) -> Self {
AuditConfig {
url: url.into(),
css: css.into(),
bounding_box,
locale: locale.into(),
..Default::default()
}
}
#[cfg(not(feature = "spider"))]
pub fn new_website(_url: &str, _css: &str, _bounding_box: bool, _locale: &str) -> Self {
AuditConfig::default()
}
}
#[cfg(all(feature = "tokio", not(feature = "spider")))]
pub async fn audit(config: AuditConfig) -> Vec<Issue> {
let document = accessibility_scraper::Html::parse_document(&config.html).await;
let auditor = Auditor::new(&document, &config.css, config.bounding_box, &config.locale);
engine::audit::wcag::WCAGAAA::audit(auditor).await
}
#[cfg(feature = "spider")]
#[derive(Debug, Clone)]
pub enum AuditResults {
Page(spider::hashbrown::HashMap<String, Vec<Issue>>),
Html(Vec<Issue>),
}
#[cfg(all(feature = "spider"))]
pub async fn audit(config: &AuditConfig) -> AuditResults {
if !config.url.is_empty() {
use spider::website::Website;
let mut website: Website = Website::new(&config.url);
let mut rx2: tokio::sync::broadcast::Receiver<spider::page::Page> =
website.subscribe(16).unwrap();
let bounding_box = config.bounding_box;
let locale = config.locale.clone();
let audits = tokio::spawn(async move {
let mut issues: spider::hashbrown::HashMap<String, Vec<Issue>> =
spider::hashbrown::HashMap::new();
while let Ok(res) = rx2.recv().await {
let document = accessibility_scraper::Html::parse_document(&res.get_html()).await;
let auditor = Auditor::new(&document, &"", bounding_box, &locale);
let issue = engine::audit::wcag::WCAGAAA::audit(auditor).await;
issues.insert(res.get_url().into(), issue);
}
issues
});
website.crawl().await;
website.unsubscribe();
AuditResults::Page(audits.await.unwrap_or_default())
} else {
let document = accessibility_scraper::Html::parse_document(&config.html).await;
let auditor = Auditor::new(&document, &config.css, config.bounding_box, &config.locale);
AuditResults::Html(engine::audit::wcag::WCAGAAA::audit(auditor).await)
}
}
#[cfg(not(feature = "tokio"))]
pub fn audit(config: &AuditConfig) -> Vec<Issue> {
let document = accessibility_scraper::Html::parse_document(&config.html);
let auditor = Auditor::new(&document, &config.css, config.bounding_box, &config.locale);
engine::audit::wcag::WCAGAAA::audit(auditor)
}