diff options
| author | Maybe Waffle <waffle.lapkin@gmail.com> | 2023-01-14 12:45:20 +0000 |
|---|---|---|
| committer | Maybe Waffle <waffle.lapkin@gmail.com> | 2023-01-14 12:45:20 +0000 |
| commit | cfc01150bf9793934f504c5cfdef680c3799ddea (patch) | |
| tree | 1f8d757c8ab50db8756b17e750fa3726e5590ff7 /crates/syntax/src | |
| parent | 32be158630e0b011a24545b07282753e6de37dd3 (diff) | |
| download | rust-cfc01150bf9793934f504c5cfdef680c3799ddea.tar.gz rust-cfc01150bf9793934f504c5cfdef680c3799ddea.zip | |
implement `AstNode` for `Either`
Diffstat (limited to 'crates/syntax/src')
| -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 10c04575833..385a4e0a3ce 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}; |
