use std::sync::LazyLock;
use regex::Regex;
use yaml_rust::Yaml;
use crate::{
UserAgentParserError,
regexes::{Replacement, build_regex, from_yaml_section, optional_replacement},
};
#[derive(Debug, Clone)]
pub(crate) struct EngineRegex {
pub(crate) regex: Regex,
pub(crate) engine_replacement: Option<Replacement>,
}
static REGEXES: LazyLock<Vec<EngineRegex>> = LazyLock::new(|| {
#[inline]
fn engine(pattern: &str, name: &str) -> EngineRegex {
EngineRegex {
regex: build_regex(pattern, false).unwrap(),
engine_replacement: Some(Replacement::new(name)),
}
}
vec![
engine(r"(?i)(windows.+\sedge)/(\w+)(?:\.(\w+))?(?:\.(\w+))?", "EdgeHTML"),
engine(
r"(?i)webkit/537\.36.+(chrome)/(\d{3,}|2[89]|[3-9]\d)(?:\.(\w+))?(?:\.(\w+))?",
"Blink",
),
engine(r"(?i)(presto)/(\w+)(?:\.(\w+))?(?:\.(\w+))?", "Presto"),
engine(r"(?i)(webkit)/(\w+)(?:\.(\w+))?(?:\.(\w+))?", "WebKit"),
engine(r"(?i)(trident)/(\w+)(?:\.(\w+))?(?:\.(\w+))?", "Trident"),
engine(r"(?i)(netfront)/(\w+)(?:\.(\w+))?(?:\.(\w+))?", "NetFront"),
engine(r"(?i)(netsurf)/(\w+)(?:\.(\w+))?(?:\.(\w+))?", "NetSurf"),
engine(r"(?i)(amaya)/(\w+)(?:\.(\w+))?(?:\.(\w+))?", "Amaya"),
engine(r"(?i)(servo)/(\w+)(?:\.(\w+))?(?:\.(\w+))?", "Servo"),
engine(r"(?i)(lynx)/(\w+)(?:\.(\w+))?(?:\.(\w+))?", "Lynx"),
engine(r"(?i)(w3m)/(\w+)(?:\.(\w+))?(?:\.(\w+))?", "w3m"),
engine(r"(?i)(goanna)/(\w+)(?:\.(\w+))?(?:\.(\w+))?", "Goanna"),
engine(r"(?i)(arkweb)/(\w+)(?:\.(\w+))?(?:\.(\w+))?", "ArkWeb"),
engine(r"(?i)ekioh(flow)/(\w+)(?:\.(\w+))?(?:\.(\w+))?", "Flow"),
engine(r"(?i)(khtml)[/\s]\(?(\w+)(?:\.(\w+))?(?:\.(\w+))?", "KHTML"),
engine(r"(?i)(tasman)[/\s]\(?(\w+)(?:\.(\w+))?(?:\.(\w+))?", "Tasman"),
engine(r"(?i)(links)[/\s]\(?(\w+)(?:\.(\w+))?(?:\.(\w+))?", "Links"),
engine(r"(?i)(dillo)[/\s]\(?(\w+)(?:\.(\w+))?(?:\.(\w+))?", "Dillo"),
engine(r"(?i)(icab)[/\s]([23])(?:\.(\d+))?(?:\.(\d+))?", "iCab"),
engine(r"(?i)\blibweb", "LibWeb"),
engine(r"(?i)(rv:)(\w+)(?:\.(\w+))?(?:\.(\w+))?.+gecko", "Gecko"),
]
});
impl EngineRegex {
#[inline]
pub(crate) fn built_in_regexes() -> &'static [EngineRegex] {
®EXES
}
pub(crate) fn from_yaml(yaml: &Yaml) -> Result<Vec<EngineRegex>, UserAgentParserError> {
let yaml_engine_replacement = Yaml::String("engine_replacement".to_string());
from_yaml_section(yaml, |regex, yaml| {
Ok(EngineRegex {
regex,
engine_replacement: optional_replacement(yaml, &yaml_engine_replacement)?,
})
})
}
}