1mod nodes;
8mod ptr;
9mod support;
10
11pub use nodes::*;
12pub use ptr::{AstPtr, SyntaxNodePtr};
13
14use crate::SyntaxNode;
15
16pub trait AstNode: Sized {
20 fn can_cast(kind: crate::SyntaxKind) -> bool;
22
23 fn cast(node: SyntaxNode) -> Option<Self>;
25
26 fn syntax(&self) -> &SyntaxNode;
28}
29
30macro_rules! ast_node {
39 ($name:ident, $kind:ident) => {
40 #[derive(Clone, PartialEq, Eq, Hash)]
41 pub struct $name {
42 syntax: $crate::SyntaxNode,
43 }
44
45 impl std::fmt::Debug for $name {
46 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47 std::fmt::Debug::fmt(&self.syntax, f)
48 }
49 }
50
51 impl std::fmt::Display for $name {
52 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53 std::fmt::Display::fmt(&self.syntax.text(), f)
54 }
55 }
56
57 impl $crate::ast::AstNode for $name {
58 fn can_cast(kind: $crate::SyntaxKind) -> bool {
59 kind == $crate::SyntaxKind::$kind
60 }
61
62 fn cast(node: $crate::SyntaxNode) -> Option<Self> {
63 if Self::can_cast(node.kind()) {
64 Some(Self { syntax: node })
65 } else {
66 None
67 }
68 }
69
70 fn syntax(&self) -> &$crate::SyntaxNode {
71 &self.syntax
72 }
73 }
74 };
75}
76
77pub(crate) use ast_node;
78
79#[cfg(test)]
80mod tests;