use std::cell::RefCell;
use rdom_core::NodeId;
use crate::TuiDom;
#[derive(Debug, Default)]
pub(crate) struct PatternCache(RefCell<Option<(String, Option<regex::Regex>)>>);
impl PatternCache {
#[cfg(test)]
pub(crate) fn cell(&self) -> &RefCell<Option<(String, Option<regex::Regex>)>> {
&self.0
}
}
impl Clone for PatternCache {
fn clone(&self) -> Self {
Self::default()
}
}
pub(super) fn mismatch(dom: &TuiDom, id: NodeId, values: &[&str]) -> bool {
let Some(source) = dom.node(id).get_attribute("pattern") else {
return false;
};
let Some(ext) = dom.node(id).ext() else {
return false;
};
let mut cache = ext.form_state.get_or_init().pattern_cache.0.borrow_mut();
if cache.as_ref().is_none_or(|(s, _)| s != source) {
let compiled = regex::Regex::new(&format!("^(?:{source})$")).ok();
*cache = Some((source.to_string(), compiled));
}
let Some((_, Some(re))) = cache.as_ref() else {
return false;
};
values.iter().any(|v| !re.is_match(v))
}