123 lines
3.6 KiB
Rust
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, 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, 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<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,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|