use crate::_SourceIteratorCollect; use crate::iterator::{PosCounter, SourceIterator}; use source_stream_0::{CollectResult, CollectedSubstring, Keyword, KeywordComparatorIterator}; use std::marker::PhantomData; use std::str::CharIndices; pub struct StrCollectedSubstring<'source> { pub slice: &'source str, pub size: usize, } impl<'source> CollectedSubstring<'source> for StrCollectedSubstring<'source> { type C = char; fn compareKeyword<'keyword>(&self, kw: impl Keyword<'keyword, C = char>) -> bool { let mut kwi; match kw.startComparation(self.size) { None => return false, Some(_kwi) => kwi = _kwi, }; for c in self.slice.chars() { if !kwi.consume(c) { return false; } } return true; } } pub struct StrSourceIterator<'source, 'pos, PC: PosCounter<'pos, char>> { _source: &'source str, _iter: CharIndices<'source>, _current: Option, _posRaw: usize, _posCodePoints: usize, _posHighlevel: PC, __phantom: PhantomData<(&'pos ())>, } impl<'source, 'pos, PC: PosCounter<'pos, char>> StrSourceIterator<'source, 'pos, PC> { pub fn start(s: &'source str, pos: PC) -> Self { let mut it = s.char_indices(); let first = it.next(); return StrSourceIterator { _source: s, _iter: it, _current: first.map(|(_, c)| c), _posRaw: first.map_or(s.len(), |(p, _)| p), _posCodePoints: 0, _posHighlevel: pos, __phantom: PhantomData::default(), }; } } impl<'source, 'pos, PC: PosCounter<'pos, char>> SourceIterator<'source, 'pos> for StrSourceIterator<'source, 'pos, PC> { type C = char; type P = PC::P; type CS = StrCollectedSubstring<'source>; fn next(&mut self) -> Option { match self._current { None => return None, Some(prev) => { self._posHighlevel.update(prev); self._posCodePoints += 1; match self._iter.next() { None => { self._posRaw = self._source.len(); self._current = None; return None; } Some((p, c)) => { self._posRaw = p; self._current = Some(c); return Some(c); } } } } } fn current(&self) -> Option { return self._current; } fn pos(&self) -> PC::P { return self._posHighlevel.export(); } fn collect( &mut self, scope: &mut impl _SourceIteratorCollect::Lambda, ) -> CollectResult> { if self._current.is_none() { return CollectResult::EOF; } let startPosRaw = self._posRaw; let startPosCodePoints = self._posCodePoints; match scope.collect(&mut _SourceIteratorCollect::DefaultImpl::wrap(self)) { false => return CollectResult::NotMatches, true => { let slice: &'source str; match self._current { None => slice = &self._source[startPosRaw..], Some(_) => slice = &self._source[startPosRaw..self._posRaw], } return CollectResult::Matches(StrCollectedSubstring { slice: slice, size: self._posCodePoints - startPosCodePoints, }); } } } }