source-stream-0.rs/default-streams/src/iterators/str.rs

123 lines
3.6 KiB
Rust

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, C = char>> {
_source: &'source str,
_iter: CharIndices<'source>,
_current: Option<char>,
_posRaw: usize,
_posCodePoints: usize,
_posHighlevel: PC,
__phantom: PhantomData<(&'pos ())>,
}
impl<'source, 'pos, PC: PosCounter<'pos, C = char>> StrSourceIterator<'source, 'pos, PC> {
pub fn start(s: &'source str) -> 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: PC::init(),
__phantom: PhantomData::default(),
};
}
}
impl<'source, 'pos, PC: PosCounter<'pos, C = 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<char> {
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<char> {
return self._current;
}
fn pos(&self) -> PC::P {
return self._posHighlevel.export();
}
fn collect(
&mut self,
scope: &mut impl _SourceIteratorCollect::Lambda<C = char>,
) -> CollectResult<StrCollectedSubstring<'source>> {
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,
});
}
}
}
}