use cstree::text::TextRange;
use omena_syntax::{StyleDialect, SyntaxKind};
use crate::{at_rule_spec, scss_at_rule_spec};
use super::StyleFactSink;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParsedAtRuleFact {
pub name: String,
pub node_kind: Option<SyntaxKind>,
pub range: TextRange,
}
pub(crate) fn collect_at_rule_facts_from_sink(sink: &StyleFactSink<'_>) -> Vec<ParsedAtRuleFact> {
sink.tokens()
.iter()
.filter(|token| token.kind == SyntaxKind::AtKeyword)
.map(|token| at_rule_fact_from_cst_token(sink.text(), token.range, sink.dialect()))
.collect()
}
fn at_rule_fact_from_cst_token(
text: &str,
range: TextRange,
dialect: StyleDialect,
) -> ParsedAtRuleFact {
let start = u32::from(range.start()) as usize;
let end = u32::from(range.end()) as usize;
let source_text = text.get(start..end).unwrap_or_default();
let css_spec = at_rule_spec(source_text);
let node_kind = css_spec
.or_else(|| match dialect {
StyleDialect::Scss | StyleDialect::Sass => scss_at_rule_spec(source_text),
StyleDialect::Css | StyleDialect::Less => None,
})
.map(|spec| spec.node_kind);
let name = if css_spec.is_some() {
source_text.to_ascii_lowercase()
} else {
source_text.to_string()
};
ParsedAtRuleFact {
name,
node_kind,
range,
}
}