Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/syntax/src/ast.rs')
| -rw-r--r-- | crates/syntax/src/ast.rs | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/crates/syntax/src/ast.rs b/crates/syntax/src/ast.rs index 10c0457583..385a4e0a3c 100644 --- a/crates/syntax/src/ast.rs +++ b/crates/syntax/src/ast.rs @@ -13,6 +13,8 @@ pub mod prec; use std::marker::PhantomData; +use itertools::Either; + use crate::{ syntax_node::{SyntaxNode, SyntaxNodeChildren, SyntaxToken}, SyntaxKind, @@ -98,6 +100,34 @@ impl<N: AstNode> Iterator for AstChildren<N> { } } +impl<L, R> AstNode for Either<L, R> +where + L: AstNode, + R: AstNode, +{ + fn can_cast(kind: SyntaxKind) -> bool + where + Self: Sized, + { + L::can_cast(kind) || R::can_cast(kind) + } + + fn cast(syntax: SyntaxNode) -> Option<Self> + where + Self: Sized, + { + if L::can_cast(syntax.kind()) { + L::cast(syntax).map(Either::Left) + } else { + R::cast(syntax).map(Either::Right) + } + } + + fn syntax(&self) -> &SyntaxNode { + self.as_ref().either(L::syntax, R::syntax) + } +} + mod support { use super::{AstChildren, AstNode, SyntaxKind, SyntaxNode, SyntaxToken}; |