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 span(&self) -> Span;
11 fn self_metadata(&self) -> CssMetadata;
13 fn subtree_metadata(&self) -> CssMetadata;
15 fn get_property(&self, kind: PropertyKind) -> Option<Cursor>;
17}
18
19#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
24pub struct NodeKey {
25 address: usize,
26 node_id: NodeId,
27}
28
29impl NodeKey {
30 fn of<T: ?Sized>(value: &T, node_id: NodeId) -> Self {
31 Self { address: (std::ptr::from_ref(value) as *const ()).addr(), node_id }
32 }
33}
34
35#[derive(Clone, Copy)]
37pub struct VisitNode<'n> {
38 span: Span,
39 pub node_id: Option<NodeId>,
40 source: Option<&'n dyn QueryNodeData>,
41}
42
43impl<'n> VisitNode<'n> {
44 #[inline]
46 pub(crate) fn new(node_id: NodeId, source: &'n dyn QueryNodeData) -> Self {
47 Self { span: Span::DUMMY, node_id: Some(node_id), source: Some(source) }
48 }
49
50 #[inline]
52 pub fn new_transparent(span: Span) -> Self {
53 Self { span, node_id: None, source: None }
54 }
55
56 #[inline]
58 pub fn span(&self) -> Span {
59 self.source.map_or(self.span, QueryNodeData::span)
60 }
61
62 #[inline]
64 pub fn key(&self) -> Option<NodeKey> {
65 self.source.zip(self.node_id).map(|(source, node_id)| NodeKey::of(source, node_id))
66 }
67
68 #[inline]
70 pub fn subtree_metadata(&self) -> CssMetadata {
71 self.source.map(QueryNodeData::subtree_metadata).unwrap_or_default()
72 }
73
74 #[inline]
76 pub fn self_metadata(&self) -> CssMetadata {
77 self.source.map(QueryNodeData::self_metadata).unwrap_or_default()
78 }
79
80 #[inline]
82 pub fn property(&self, kind: PropertyKind) -> Option<Cursor> {
83 self.source.and_then(|s| s.get_property(kind))
84 }
85}