css_ast/visit/
visit_node.rs1use css_lexer::Span;
2use css_parse::Cursor;
3
4use crate::{CssMetadata, PropertyKind};
5
6use super::NodeId;
7
8pub(crate) trait QueryNodeData {
9 fn self_metadata(&self) -> CssMetadata;
11 fn subtree_metadata(&self) -> CssMetadata;
13 fn get_property(&self, kind: PropertyKind) -> Option<Cursor>;
15}
16
17#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
22pub struct NodeKey {
23 address: usize,
24 node_id: NodeId,
25}
26
27impl NodeKey {
28 fn of<T: ?Sized>(value: &T, node_id: NodeId) -> Self {
29 Self { address: (std::ptr::from_ref(value) as *const ()).addr(), node_id }
30 }
31}
32
33#[derive(Clone, Copy)]
35pub struct VisitNode<'n> {
36 pub span: Span,
37 pub node_id: Option<NodeId>,
38 source: Option<&'n dyn QueryNodeData>,
39}
40
41impl<'n> VisitNode<'n> {
42 #[inline]
44 pub(crate) fn new(span: Span, node_id: NodeId, source: &'n dyn QueryNodeData) -> Self {
45 Self { span, node_id: Some(node_id), source: Some(source) }
46 }
47
48 #[inline]
50 pub fn new_transparent(span: Span) -> Self {
51 Self { span, node_id: None, source: None }
52 }
53
54 #[inline]
56 pub fn key(&self) -> Option<NodeKey> {
57 self.source.zip(self.node_id).map(|(source, node_id)| NodeKey::of(source, node_id))
58 }
59
60 #[inline]
62 pub fn subtree_metadata(&self) -> CssMetadata {
63 self.source.map(QueryNodeData::subtree_metadata).unwrap_or_default()
64 }
65
66 #[inline]
68 pub fn self_metadata(&self) -> CssMetadata {
69 self.source.map(QueryNodeData::self_metadata).unwrap_or_default()
70 }
71
72 #[inline]
74 pub fn property(&self, kind: PropertyKind) -> Option<Cursor> {
75 self.source.and_then(|s| s.get_property(kind))
76 }
77}