From ab5463e2749330be6846886c21e98c83caca8598 Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Sun, 27 Oct 2024 22:06:08 +0100 Subject: [PATCH] Use iterators for by_kind instead of introducing separate structs This makes this API actually useful from the outside - there is no lifetime problem with the matcher callback, and we can remap the raw Kind to the Language::Kind on the fly. --- src/api.rs | 56 +++++++++--------------------------------------------- src/lib.rs | 3 +-- 2 files changed, 10 insertions(+), 49 deletions(-) diff --git a/src/api.rs b/src/api.rs index 72ef0a9..cd86d9d 100644 --- a/src/api.rs +++ b/src/api.rs @@ -441,30 +441,11 @@ impl Iterator for SyntaxNodeChildren { } impl SyntaxNodeChildren { - pub fn by_kind<'a>( - self, - matcher: &'a dyn Fn(SyntaxKind) -> bool, - ) -> SyntaxNodeChildrenByKind<'a, L> { - SyntaxNodeChildrenByKind { raw: self.raw.by_kind(matcher), _p: PhantomData } - } -} - -#[derive(Clone)] -pub struct SyntaxNodeChildrenByKind<'a, L: Language> { - raw: cursor::SyntaxNodeChildrenByKind<&'a dyn Fn(SyntaxKind) -> bool>, - _p: PhantomData, -} - -impl<'a, L: Language> Iterator for SyntaxNodeChildrenByKind<'a, L> { - type Item = SyntaxNode; - fn next(&mut self) -> Option { - self.raw.next().map(SyntaxNode::from) - } -} - -impl<'a, L: Language> fmt::Debug for SyntaxNodeChildrenByKind<'a, L> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("SyntaxNodeChildrenByKind").finish() + pub fn by_kind(self, matcher: impl Fn(L::Kind) -> bool) -> impl Iterator> { + self.raw + .by_kind(move |raw_kind| matcher(L::kind_from_raw(raw_kind))) + .into_iter() + .map(SyntaxNode::from) } } @@ -482,30 +463,11 @@ impl Iterator for SyntaxElementChildren { } impl SyntaxElementChildren { - pub fn by_kind<'a>( + pub fn by_kind( self, - matcher: &'a dyn Fn(SyntaxKind) -> bool, - ) -> SyntaxElementChildrenByKind<'a, L> { - SyntaxElementChildrenByKind { raw: self.raw.by_kind(matcher), _p: PhantomData } - } -} - -#[derive(Clone)] -pub struct SyntaxElementChildrenByKind<'a, L: Language> { - raw: cursor::SyntaxElementChildrenByKind<&'a dyn Fn(SyntaxKind) -> bool>, - _p: PhantomData, -} - -impl<'a, L: Language> Iterator for SyntaxElementChildrenByKind<'a, L> { - type Item = SyntaxElement; - fn next(&mut self) -> Option { - self.raw.next().map(NodeOrToken::from) - } -} - -impl<'a, L: Language> fmt::Debug for SyntaxElementChildrenByKind<'a, L> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("SyntaxElementChildrenByKind").finish() + matcher: impl Fn(L::Kind) -> bool, + ) -> impl Iterator> { + self.raw.by_kind(move |raw_kind| matcher(L::kind_from_raw(raw_kind))).map(NodeOrToken::from) } } diff --git a/src/lib.rs b/src/lib.rs index 066d8c5..bb8f30d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,8 +30,7 @@ pub use text_size::{TextLen, TextRange, TextSize}; pub use crate::{ api::{ - Language, SyntaxElement, SyntaxElementChildren, SyntaxElementChildrenByKind, SyntaxNode, - SyntaxNodeChildren, SyntaxNodeChildrenByKind, SyntaxToken, + Language, SyntaxElement, SyntaxElementChildren, SyntaxNode, SyntaxNodeChildren, SyntaxToken, }, green::{ Checkpoint, Children, GreenNode, GreenNodeBuilder, GreenNodeData, GreenToken,