129 lines
4.0 KiB
Rust
129 lines
4.0 KiB
Rust
use crate::iterator::{_CollectScopeContext, PosCounter, SourceIterator};
|
|
use source_stream_0::{CollectResult, CollectedSubstring, Keyword, KeywordComparatorIterator, Pos};
|
|
use std::marker::PhantomData;
|
|
use std::slice::Iter;
|
|
|
|
enum _CurrentChar<C> {
|
|
UNINITIALIZED,
|
|
EOF,
|
|
Got(C),
|
|
}
|
|
|
|
pub struct ArrayCollectedSubstring<'source, C> {
|
|
pub slice: &'source [C],
|
|
}
|
|
|
|
impl<'source, C: Copy> CollectedSubstring<'source, C> for ArrayCollectedSubstring<'source, C> {
|
|
fn compareKeyword<'keyword>(&self, kw: impl Keyword<'keyword, C>) -> bool {
|
|
let mut kwi;
|
|
match kw.startComparation(self.slice.len()) {
|
|
None => return false,
|
|
Some(_kwi) => kwi = _kwi,
|
|
};
|
|
|
|
for c in self.slice.iter() {
|
|
if !kwi.consume(*c) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
pub struct ArraySourceIterator<'source, 'pos, C: Copy, P: Pos<'pos>, PC: PosCounter<'pos, C, P>> {
|
|
_source: &'source [C],
|
|
_iter: Iter<'source, C>,
|
|
_current: _CurrentChar<&'source C>,
|
|
_posRaw: usize,
|
|
_posHighlevel: PC,
|
|
__phantom1: PhantomData<&'pos ()>,
|
|
__phantom2: PhantomData<P>,
|
|
}
|
|
|
|
impl<'source, 'pos, C: Copy, P: Pos<'pos>, PC: PosCounter<'pos, C, P>>
|
|
ArraySourceIterator<'source, 'pos, C, P, PC>
|
|
{
|
|
pub fn start(arr: &'source [C]) -> ArraySourceIterator<'source, 'pos, C, P, PC> {
|
|
return ArraySourceIterator {
|
|
_source: arr,
|
|
_iter: arr.iter(),
|
|
_current: _CurrentChar::UNINITIALIZED,
|
|
_posRaw: 0,
|
|
_posHighlevel: PC::init(),
|
|
__phantom1: PhantomData::default(),
|
|
__phantom2: PhantomData::default(),
|
|
};
|
|
}
|
|
}
|
|
|
|
impl<'source, 'pos, C: Copy, P: Pos<'pos>, PC: PosCounter<'pos, C, P>>
|
|
_CollectScopeContext<'source, C> for ArraySourceIterator<'source, 'pos, C, P, PC>
|
|
{
|
|
fn next(&mut self) -> Option<C> {
|
|
match self._iter.next() {
|
|
None => {
|
|
if let _CurrentChar::Got(_) = self._current {
|
|
self._posHighlevel.update(None);
|
|
self._posRaw += 1;
|
|
}
|
|
self._current = _CurrentChar::EOF;
|
|
return None;
|
|
}
|
|
Some(c) => {
|
|
self._posHighlevel.update(Some(*c));
|
|
if let _CurrentChar::Got(_) = self._current {
|
|
self._posRaw += 1;
|
|
}
|
|
self._current = _CurrentChar::Got(c);
|
|
return Some(*c);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn current(&mut self) -> Option<C> {
|
|
match self._current {
|
|
_CurrentChar::UNINITIALIZED => return self.next(),
|
|
_CurrentChar::EOF => return None,
|
|
_CurrentChar::Got(c) => return Some(*c),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'source, 'pos, C: Copy, P: Pos<'pos>, PC: PosCounter<'pos, C, P>>
|
|
SourceIterator<'source, 'pos, C, P, ArrayCollectedSubstring<'source, C>>
|
|
for ArraySourceIterator<'source, 'pos, C, P, PC>
|
|
{
|
|
fn pos(&self) -> P {
|
|
return self._posHighlevel.export();
|
|
}
|
|
|
|
type CollectScopeContext = ArraySourceIterator<'source, 'pos, C, P, PC>;
|
|
|
|
fn collect(
|
|
&mut self,
|
|
scope: impl FnOnce(&mut Self::CollectScopeContext) -> bool,
|
|
) -> CollectResult<ArrayCollectedSubstring<'source, C>> {
|
|
match self._current {
|
|
_CurrentChar::EOF => return CollectResult::EOF,
|
|
_CurrentChar::UNINITIALIZED => {}
|
|
_CurrentChar::Got(_) => {}
|
|
}
|
|
|
|
let startPosRaw = self._posRaw;
|
|
|
|
match scope(self) {
|
|
false => return CollectResult::NotMatches,
|
|
true => {
|
|
let slice: &'source [C];
|
|
match self._current {
|
|
_CurrentChar::EOF => slice = &self._source[startPosRaw..],
|
|
_CurrentChar::UNINITIALIZED => slice = &[],
|
|
_CurrentChar::Got(_) => slice = &self._source[startPosRaw..self._posRaw],
|
|
}
|
|
return CollectResult::Matches(ArrayCollectedSubstring { slice: slice });
|
|
}
|
|
}
|
|
}
|
|
}
|