Redesigned source stream to fold same checks and increase performance

This commit is contained in:
Andrew Golovashevich 2025-11-19 01:28:29 +03:00
parent 11541e9396
commit 1200f99e38
13 changed files with 306 additions and 373 deletions

View File

@ -8,7 +8,7 @@ use source_stream_0_converter_0::{
};
use source_stream_0_default_streams_0::SourceStreamOverIterator;
use source_stream_0_default_streams_0::iterators::{
ArrayCollectedSubstring, ArraySourceIterator, StrSourceIterator,
ArrayCollectedSubstring, ArraySourceStream, StrSourceStream,
};
use source_stream_0_default_streams_0::pos::IndexPosCounter;
use std::marker::PhantomData;
@ -49,7 +49,7 @@ fn printAscii(a: Option<AsciiChar>) {
#[test]
fn sandbox() {
let src8 = SourceStreamOverIterator::wrap(StrSourceIterator::start(
let src8 = SourceStreamOverIterator::wrap(StrSourceStream::start(
"qwяtr",
IndexPosCounter::default(),
));

View File

@ -2,13 +2,12 @@
#![allow(non_snake_case)]
use source_stream_0::{
CollectResult, CollectedSubstring, Keyword, KeywordComparatorIterator, Pos, Predicate,
SourceStream,
CollectedSubstring, Keyword, KeywordComparatorIterator, Pos, Predicate, SourceStream,
};
use std::marker::PhantomData;
pub trait StreamConverter_Char<C> {
type WC;
pub trait StreamConverter_Char<C: Copy> {
type WC: Copy;
fn convertChar(&self, c: C) -> Self::WC;
}
@ -17,14 +16,20 @@ pub trait StreamConverter_Pos<'pos, P: Pos<'pos>> {
fn convertPos(&self, p: P) -> Self::WP;
}
pub trait StreamConverter_Substring<'source, C, CS: CollectedSubstring<'source, C = C>>:
pub trait StreamConverter_Substring<'source, C: Copy, CS: CollectedSubstring<'source, C = C>>:
StreamConverter_Char<C>
{
type WCS: CollectedSubstring<'source, C = Self::WC>;
fn convertSubstring(&self, wcs: CS) -> Self::WCS;
}
pub trait StreamConverter<'source, 'pos, C, P: Pos<'pos>, CS: CollectedSubstring<'source, C = C>>:
pub trait StreamConverter<
'source,
'pos,
C: Copy,
P: Pos<'pos>,
CS: CollectedSubstring<'source, C = C>,
>:
StreamConverter_Char<C> + StreamConverter_Pos<'pos, P> + StreamConverter_Substring<'source, C, CS>
{
}
@ -32,7 +37,7 @@ pub trait StreamConverter<'source, 'pos, C, P: Pos<'pos>, CS: CollectedSubstring
impl<
'source,
'pos,
C,
C: Copy,
P: Pos<'pos>,
CS: CollectedSubstring<'source, C = C>,
W: StreamConverter_Char<C>
@ -45,7 +50,7 @@ impl<
struct PredicateConverter<
'predicate,
'converter,
C,
C: Copy,
W: StreamConverter_Char<C>,
I: Predicate<W::WC>,
> {
@ -54,7 +59,7 @@ struct PredicateConverter<
__phantom: PhantomData<C>,
}
impl<'predicate, 'converter, C, W: StreamConverter_Char<C>, I: Predicate<W::WC>>
impl<'predicate, 'converter, C: Copy, W: StreamConverter_Char<C>, I: Predicate<W::WC>>
PredicateConverter<'predicate, 'converter, C, W, I>
{
fn wrap(pred: &'predicate mut I, converter: &'converter W) -> Self {
@ -66,7 +71,7 @@ impl<'predicate, 'converter, C, W: StreamConverter_Char<C>, I: Predicate<W::WC>>
}
}
impl<'predicate, 'converter, C, W: StreamConverter_Char<C>, I: Predicate<W::WC>> Predicate<C>
impl<'predicate, 'converter, C: Copy, W: StreamConverter_Char<C>, I: Predicate<W::WC>> Predicate<C>
for PredicateConverter<'predicate, 'converter, C, W, I>
{
fn check(&mut self, chr: C) -> bool {
@ -77,7 +82,7 @@ impl<'predicate, 'converter, C, W: StreamConverter_Char<C>, I: Predicate<W::WC>>
pub struct ConvertedSourceStream<
'source,
'pos,
C,
C: Copy,
P: Pos<'pos>,
CS: CollectedSubstring<'source, C = C>,
W: StreamConverter<'source, 'pos, C, P, CS>,
@ -91,7 +96,7 @@ pub struct ConvertedSourceStream<
impl<
'source,
'pos,
C,
C: Copy,
P: Pos<'pos>,
CS: CollectedSubstring<'source, C = C>,
W: StreamConverter<'source, 'pos, C, P, CS>,
@ -110,7 +115,7 @@ impl<
impl<
'source,
'pos,
C,
C: Copy,
P: Pos<'pos>,
CS: CollectedSubstring<'source, C = C>,
W: StreamConverter<'source, 'pos, C, P, CS>,
@ -121,35 +126,28 @@ impl<
type P = W::WP;
type CS = W::WCS;
fn skip(&mut self, predicate: &mut impl Predicate<W::WC>) -> bool {
self._src
.skip(&mut PredicateConverter::wrap(predicate, &self._converter))
fn skipNext(&mut self, predicate: &mut impl Predicate<Self::C>) -> Option<Self::C> {
return self
._src
.skipNext(&mut PredicateConverter::wrap(predicate, &self._converter))
.map(|c| self._converter.convertChar(c));
}
fn collect(&mut self, predicate: &mut impl Predicate<W::WC>) -> CollectResult<W::WCS> {
match self
fn collect(&mut self, predicate: &mut impl Predicate<Self::C>) -> (Self::CS, Option<Self::C>) {
let (cs, wrongChar) = self
._src
.collect(&mut PredicateConverter::wrap(predicate, &self._converter))
{
CollectResult::EOF => return CollectResult::EOF,
CollectResult::NotMatches => return CollectResult::NotMatches,
CollectResult::Matches(cs) => {
return CollectResult::Matches(self._converter.convertSubstring(cs));
}
}
.collect(&mut PredicateConverter::wrap(predicate, &self._converter));
return (
self._converter.convertSubstring(cs),
wrongChar.map(|c| self._converter.convertChar(c)),
);
}
fn pos(&self) -> W::WP {
return self._converter.convertPos(self._src.pos());
}
fn currentChar(&self) -> Option<W::WC> {
return self
._src
.currentChar()
.map(|c| self._converter.convertChar(c));
}
fn nextChar(&mut self) -> Option<W::WC> {
return self._src.nextChar().map(|c| self._converter.convertChar(c));
}
@ -158,7 +156,7 @@ impl<
pub struct KeywordDeconverted<
'keyword,
'converter,
C,
C: Copy,
W: StreamConverter_Char<C>,
I: Keyword<W::WC>,
> {
@ -167,7 +165,7 @@ pub struct KeywordDeconverted<
__phantom: PhantomData<C>,
}
impl<'keyword, 'converter, C, W: StreamConverter_Char<C>, I: Keyword<W::WC>>
impl<'keyword, 'converter, C: Copy, W: StreamConverter_Char<C>, I: Keyword<W::WC>>
KeywordDeconverted<'keyword, 'converter, C, W, I>
{
pub fn unwrap(kw: &'keyword I, converter: &'converter W) -> Self {
@ -179,7 +177,7 @@ impl<'keyword, 'converter, C, W: StreamConverter_Char<C>, I: Keyword<W::WC>>
}
}
impl<'keyword, 'converter, C, W: StreamConverter_Char<C>, I: Keyword<W::WC>> Keyword<C>
impl<'keyword, 'converter, C: Copy, W: StreamConverter_Char<C>, I: Keyword<W::WC>> Keyword<C>
for KeywordDeconverted<'keyword, 'converter, C, W, I>
{
fn startComparation<'self_>(
@ -200,7 +198,7 @@ impl<'keyword, 'converter, C, W: StreamConverter_Char<C>, I: Keyword<W::WC>> Key
struct KeywordComparatorConverter<
'keyword,
'converter,
C,
C: Copy,
W: StreamConverter_Char<C>,
I: KeywordComparatorIterator<'keyword, W::WC>,
> {
@ -212,7 +210,7 @@ struct KeywordComparatorConverter<
impl<
'keyword,
'converter,
C,
C: Copy,
W: StreamConverter_Char<C>,
I: KeywordComparatorIterator<'keyword, W::WC>,
> KeywordComparatorIterator<'keyword, C>
@ -223,16 +221,16 @@ impl<
}
}
pub trait StreamConverter_Char_Noop<C> {}
pub trait StreamConverter_Char_Noop<C: Copy> {}
pub trait StreamConverter_Pos_Noop<'pos, P: Pos<'pos>> {}
pub trait StreamConverter_Substring_Noop<'source, C, CS: CollectedSubstring<'source, C = C>>:
pub trait StreamConverter_Substring_Noop<'source, C: Copy, CS: CollectedSubstring<'source, C = C>>:
StreamConverter_Char<C>
{
}
impl<C, W: StreamConverter_Char_Noop<C>> StreamConverter_Char<C> for W {
impl<C: Copy, W: StreamConverter_Char_Noop<C>> StreamConverter_Char<C> for W {
type WC = C;
fn convertChar(&self, c: C) -> Self::WC {

View File

@ -1,32 +0,0 @@
use source_stream_0::{SourceStream};
use crate::iterators::{ArraySourceIterator};
use crate::pos::{IndexPosCounter};
use crate::SourceIterator;
#[test]
fn sandbox() {
let mut z = ArraySourceIterator::start(b"12\n34", IndexPosCounter::default());
println!("{}", z.pos());
z.next();
println!("{} ", z.pos());
z.next();
println!("{}", z.pos());
z.next();
println!("{} ", z.pos());
z.next();
println!("{} ", z.pos());
z.next();
println!("{} ", z.pos());
z.next();
println!("{} ", z.pos());
z.next();
println!("{} ", z.pos());
z.next();
println!("{} ", z.pos());
z.next();
println!("{} ", z.pos());
z.next();
return;
}

View File

@ -1,65 +1,9 @@
use source_stream_0::{CollectResult, CollectedSubstring, Pos};
use source_stream_0::Pos;
pub trait PosCounter<'pos, C> {
pub trait PosCounter<'pos, C: Copy> {
type P: Pos<'pos>;
fn update(&mut self, c: C);
fn export(&self) -> Self::P;
}
pub trait SourceIterator<'source, 'pos> {
type C;
type P: Pos<'pos>;
type CS: CollectedSubstring<'source, C = Self::C>;
fn next(&mut self) -> Option<Self::C>;
fn current(&self) -> Option<Self::C>;
fn pos(&self) -> Self::P;
fn collect(&mut self, scope: &mut impl _SourceIteratorCollect::Lambda<C=Self::C>) -> CollectResult<Self::CS>;
}
pub mod _SourceIteratorCollect {
use crate::SourceIterator;
use std::marker::PhantomData;
pub trait Context<'source> {
type C;
fn next(&mut self) -> Option<Self::C>;
fn current(&self) -> Option<Self::C>;
}
pub trait Lambda {
type C;
fn collect<'source>(&mut self, src: &mut impl Context<'source, C=Self::C>) -> bool;
}
pub struct DefaultImpl<'source, 'pos, 'iter, I: SourceIterator<'source, 'pos>> {
_full: &'iter mut I,
__phantom: PhantomData<(&'source (), &'pos ())>,
}
impl<'source, 'pos, 'iter, I: SourceIterator<'source, 'pos>> DefaultImpl<'source, 'pos, 'iter, I> {
pub fn wrap(s: &'iter mut I) -> Self {
return DefaultImpl {
_full: s,
__phantom: PhantomData::default(),
};
}
}
impl<'source, 'pos, 'iter, I: SourceIterator<'source, 'pos>> Context<'source>
for DefaultImpl<'source, 'pos, 'iter, I>
{
type C = I::C;
fn next(&mut self) -> Option<Self::C> {
return self._full.next();
}
fn current(&self) -> Option<Self::C> {
return self._full.current();
}
}
}

View File

@ -1,6 +1,7 @@
use crate::_SourceIteratorCollect;
use crate::iterator::{PosCounter, SourceIterator};
use source_stream_0::{CollectResult, CollectedSubstring, Keyword, KeywordComparatorIterator};
use crate::iterator::{PosCounter};
use source_stream_0::{
CollectedSubstring, Keyword, KeywordComparatorIterator, Predicate, SourceStream,
};
use std::marker::PhantomData;
use std::slice::Iter;
@ -27,74 +28,103 @@ impl<'source, C: Copy> CollectedSubstring<'source> for ArrayCollectedSubstring<'
}
}
pub struct ArraySourceIterator<'source, 'pos, C: Copy, PC: PosCounter<'pos, C>> {
pub struct ArraySourceStream<'source, 'pos, C: Copy, PC: PosCounter<'pos, C>> {
_source: &'source [C],
_iter: Iter<'source, C>,
_current: Option<&'source C>,
__iter: Iter<'source, C>,
_current: C,
_posRaw: usize,
_posHighlevel: PC,
_isEnded: bool,
__phantom: PhantomData<&'pos ()>,
}
impl<'source, 'pos, C: Copy, PC: PosCounter<'pos, C>> ArraySourceIterator<'source, 'pos, C, PC> {
pub fn start(arr: &'source [C], pos: PC) -> ArraySourceIterator<'source, 'pos, C, PC> {
let mut it = arr.iter();
let first = it.next();
return ArraySourceIterator {
impl<'source, 'pos, C: Copy, PC: PosCounter<'pos, C>> ArraySourceStream<'source, 'pos, C, PC> {
pub fn start(arr: &'source [C], pos: PC) -> Option<(Self, C)> {
let mut iter = arr.iter();
let first = iter.next().copied();
match first {
None => None,
Some(c) => {
let stream = ArraySourceStream {
_source: arr,
_iter: it,
_current: first,
__iter: iter,
_current: c,
_posRaw: 0,
_posHighlevel: pos,
_isEnded: false,
__phantom: PhantomData::default(),
};
return Some((stream, c));
}
}
}
}
impl<'source, 'pos, C: Copy, PC: PosCounter<'pos, C>> SourceIterator<'source, 'pos>
for ArraySourceIterator<'source, 'pos, C, PC>
impl<'source, 'pos, C: Copy, PC: PosCounter<'pos, C>> ArraySourceStream<'source, 'pos, C, PC> {
fn _next(&mut self) -> Option<C> {
if !self._isEnded {
self._posHighlevel.update(self._current);
self._posRaw += 1;
}
match self.__iter.next() {
None => return None,
Some(c) => {
self._isEnded = true;
self._current = *c;
return Some(self._current);
}
}
}
}
impl<'source, 'pos, C: Copy, PC: PosCounter<'pos, C>> SourceStream<'source, 'pos>
for ArraySourceStream<'source, 'pos, C, PC>
{
type C = C;
type P = PC::P;
type CS = ArrayCollectedSubstring<'source, C>;
fn next(&mut self) -> Option<C> {
if let Some(c) = self._current {
self._posHighlevel.update(*c);
self._posRaw += 1;
self._current = self._iter.next();
fn skipNext(&mut self, predicate: &mut impl Predicate<Self::C>) -> Option<Self::C> {
loop {
match self._next() {
None => return None,
Some(c) => match predicate.check(c) {
true => continue,
false => return Some(c),
},
}
}
return self._current.map(|c| *c);
}
fn current(&self) -> Option<C> {
return self._current.map(|c| *c);
fn collect(&mut self, predicate: &mut impl Predicate<Self::C>) -> (Self::CS, Option<Self::C>) {
let startPosRaw = self._posRaw;
let wrongChar: Option<C>;
loop {
match self._next() {
None => {
wrongChar = None;
break;
}
Some(c) => match predicate.check(c) {
true => continue,
false => {
wrongChar = Some(c);
break;
}
},
}
}
let slice = &self._source[startPosRaw..self._posRaw];
return (ArrayCollectedSubstring { slice: slice }, wrongChar);
}
fn pos(&self) -> Self::P {
return self._posHighlevel.export();
}
fn collect(
&mut self,
scope: &mut impl _SourceIteratorCollect::Lambda<C = C>,
) -> CollectResult<ArrayCollectedSubstring<'source, C>> {
if self._current.is_none() {
return CollectResult::EOF;
}
let startPosRaw = self._posRaw;
match scope.collect(&mut _SourceIteratorCollect::DefaultImpl::wrap(self)) {
false => return CollectResult::NotMatches,
true => {
let slice: &'source [C];
match self._current {
None => slice = &self._source[startPosRaw..],
Some(_) => slice = &self._source[startPosRaw..self._posRaw],
}
return CollectResult::Matches(ArrayCollectedSubstring { slice: slice });
}
}
fn nextChar(&mut self) -> Option<Self::C> {
return self._next();
}
}

View File

@ -0,0 +1,62 @@
use crate::PosCounter;
use source_stream_0::{CollectedSubstring, Pos, Predicate, SourceStream};
use std::marker::PhantomData;
pub struct EmptySourceStream<
'source,
'pos,
C: Copy,
P: Pos<'pos>,
CS: CollectedSubstring<'source, C=C>,
PC: PosCounter<'pos, C, P=P>,
> {
_pos: PC,
__phantom: PhantomData<(&'source (), &'pos (), P, CS)>,
}
impl<
'source,
'pos,
C: Copy,
P: Pos<'pos>,
CS: CollectedSubstring<'source, C=C>,
PC: PosCounter<'pos, C, P=P>,
> EmptySourceStream<'source, 'pos, C, P, CS, PC>
{
pub fn start(pos: PC) -> (Self, Option<C>) {
let stream = EmptySourceStream {
_pos: pos,
__phantom: PhantomData::default()
};
return (stream, None);
}
}
impl<
'source,
'pos,
C: Copy,
P: Pos<'pos>,
CS: CollectedSubstring<'source, C=C>,
PC: PosCounter<'pos, C, P=P>,
> SourceStream<'source, 'pos> for EmptySourceStream<'source, 'pos, C, P, CS, PC>
{
type C = C;
type P = P;
type CS = CS;
fn skipNext(&mut self, predicate: &mut impl Predicate<Self::C>) -> Option<Self::C> {
return None;
}
fn collect(&mut self, predicate: &mut impl Predicate<Self::C>) -> (Self::CS, Option<Self::C>) {
panic!("How about to check first char of substring being collected first");
}
fn pos(&self) -> Self::P {
return self._pos.export();
}
fn nextChar(&mut self) -> Option<Self::C> {
return None;
}
}

View File

@ -1,8 +1,8 @@
mod str;
mod array;
mod empty;
pub use str::StrCollectedSubstring;
pub use str::StrSourceIterator;
pub use str::StrSourceStream;
pub use array::ArrayCollectedSubstring;
pub use array::ArraySourceIterator;
pub use array::ArraySourceStream;

View File

@ -1,6 +1,7 @@
use crate::_SourceIteratorCollect;
use crate::iterator::{PosCounter, SourceIterator};
use source_stream_0::{CollectResult, CollectedSubstring, Keyword, KeywordComparatorIterator};
use crate::iterator::{PosCounter};
use source_stream_0::{
CollectedSubstring, Keyword, KeywordComparatorIterator, Predicate, SourceStream,
};
use std::marker::PhantomData;
use std::str::CharIndices;
@ -29,94 +30,113 @@ impl<'source> CollectedSubstring<'source> for StrCollectedSubstring<'source> {
}
}
pub struct StrSourceIterator<'source, 'pos, PC: PosCounter<'pos, char>> {
pub struct StrSourceStream<'source, 'pos, PC: PosCounter<'pos, char>> {
_source: &'source str,
_iter: CharIndices<'source>,
_current: Option<char>,
__iter: CharIndices<'source>,
_current: char,
_posRaw: usize,
_posCodePoints: usize,
_posHighlevel: PC,
_isEnded: bool,
__phantom: PhantomData<&'pos ()>,
}
impl<'source, 'pos, PC: PosCounter<'pos, char>> StrSourceIterator<'source, 'pos, PC> {
pub fn start(s: &'source str, pos: PC) -> Self {
impl<'source, 'pos, PC: PosCounter<'pos, char>> StrSourceStream<'source, 'pos, PC> {
pub fn start(s: &'source str, pos: PC) -> Option<(Self, char)> {
let mut it = s.char_indices();
let first = it.next();
return StrSourceIterator {
match first {
None => return None,
Some((p, c)) => {
let stream = StrSourceStream {
_source: s,
_iter: it,
_current: first.map(|(_, c)| c),
_posRaw: first.map_or(s.len(), |(p, _)| p),
__iter: it,
_current: c,
_posRaw: p,
_posCodePoints: 0,
_posHighlevel: pos,
_isEnded: false,
__phantom: PhantomData::default(),
};
return Some((stream, c));
}
}
}
}
impl<'source, 'pos, PC: PosCounter<'pos, char>> SourceIterator<'source, 'pos>
for StrSourceIterator<'source, 'pos, PC>
impl<'source, 'pos, PC: PosCounter<'pos, char>> StrSourceStream<'source, 'pos, PC> {
fn _next(&mut self) -> Option<char> {
if !self._isEnded {
self._posHighlevel.update(self._current);
self._posCodePoints += 1;
}
match self.__iter.next() {
None => return None,
Some((p, c)) => {
self._isEnded = true;
self._posRaw = p;
self._current = c;
return Some(self._current);
}
}
}
}
impl<'source, 'pos, PC: PosCounter<'pos, char>> SourceStream<'source, 'pos>
for StrSourceStream<'source, 'pos, PC>
{
type C = char;
type P = PC::P;
type CS = StrCollectedSubstring<'source>;
fn next(&mut self) -> Option<char> {
match self._current {
fn skipNext(&mut self, predicate: &mut impl Predicate<Self::C>) -> Option<Self::C> {
loop {
match self._next() {
None => return None,
Some(prev) => {
self._posHighlevel.update(prev);
self._posCodePoints += 1;
Some(c) => match predicate.check(c) {
true => continue,
false => return Some(c),
},
}
}
}
match self._iter.next() {
fn collect(&mut self, predicate: &mut impl Predicate<Self::C>) -> (Self::CS, Option<Self::C>) {
let startPosRaw = self._posRaw;
let startPosCP = self._posCodePoints;
let wrongChar: Option<char>;
loop {
match self._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);
}
wrongChar = None;
break;
}
Some(c) => match predicate.check(c) {
true => continue,
false => {
wrongChar = Some(c);
break;
}
},
}
}
fn current(&self) -> Option<char> {
return self._current;
let slice = &self._source[startPosRaw..self._posRaw];
return (
StrCollectedSubstring {
slice: slice,
size: self._posCodePoints - startPosCP,
},
wrongChar,
);
}
fn pos(&self) -> PC::P {
fn pos(&self) -> Self::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,
});
}
}
fn nextChar(&mut self) -> Option<Self::C> {
return self._next();
}
}

View File

@ -1,11 +1,5 @@
mod iterator;
mod stream;
pub use iterator::PosCounter;
pub use iterator::SourceIterator;
pub use iterator::_SourceIteratorCollect;
pub use stream::SourceStreamOverIterator;
pub mod pos;
pub mod iterators;
mod _sandbox;

View File

@ -10,7 +10,7 @@ impl Default for IndexPosCounter {
}
}
impl<C> PosCounter<'static, C> for IndexPosCounter {
impl<C: Copy> PosCounter<'static, C> for IndexPosCounter {
type P = usize;
fn update(&mut self, _: C) {

View File

@ -7,11 +7,10 @@ impl Default for NopPosCounter {
}
}
impl<C> PosCounter<'static, C> for NopPosCounter {
impl<C: Copy> PosCounter<'static, C> for NopPosCounter {
type P = ();
fn update(&mut self, _: C) {}
fn export(&self) {}
}

View File

@ -1,93 +0,0 @@
use crate::_SourceIteratorCollect;
use crate::iterator::SourceIterator;
use source_stream_0::{CollectResult, Predicate, SourceStream};
use std::marker::PhantomData;
pub struct SourceStreamOverIterator<'source, 'pos, I: SourceIterator<'source, 'pos>> {
_iter: I,
__phantom: PhantomData<(&'source (), &'pos ())>,
}
impl<'source, 'pos, I: SourceIterator<'source, 'pos>> SourceStreamOverIterator<'source, 'pos, I> {
pub fn wrap(iter: I) -> SourceStreamOverIterator<'source, 'pos, I> {
return SourceStreamOverIterator {
_iter: iter,
__phantom: PhantomData::default(),
};
}
}
struct CollectFunction<'predicate, C, I: Predicate<C>> {
predicate: &'predicate mut I,
__phantom: PhantomData<C>
}
impl<'predicate, C, I: Predicate<C>> _SourceIteratorCollect::Lambda for CollectFunction<'predicate, C, I> {
type C = C;
fn collect<'source>(&mut self, src: &mut impl _SourceIteratorCollect::Context<'source, C = Self::C>) -> bool {
match src.current() {
Some(c) => match self.predicate.check(c) {
false => return false,
true => {}
},
None => return false,
}
loop {
match src.next() {
None => {
return true;
}
Some(c) => match self.predicate.check(c) {
true => continue,
false => return true,
},
}
}
}
}
impl<'source, 'pos, I: SourceIterator<'source, 'pos>> SourceStream<'source, 'pos>
for SourceStreamOverIterator<'source, 'pos, I>
{
type C = I::C;
type P = I::P;
type CS = I::CS;
fn skip(&mut self, predicate: &mut impl Predicate<I::C>) -> bool {
match self._iter.current() {
Some(c) => match predicate.check(c) {
false => return false,
true => {}
},
None => return true,
}
loop {
match self._iter.next() {
None => return true,
Some(c) => match predicate.check(c) {
true => continue,
false => return false,
},
}
}
}
fn collect(&mut self, predicate: &mut impl Predicate<I::C>) -> CollectResult<I::CS> {
return self._iter.collect(&mut CollectFunction { predicate, __phantom: PhantomData::default() });
}
fn pos(&self) -> I::P {
return self._iter.pos();
}
fn currentChar(&self) -> Option<I::C> {
return self._iter.current();
}
fn nextChar(&mut self) -> Option<I::C> {
return self._iter.next();
}
}

View File

@ -3,7 +3,7 @@
mod _keyword_impls;
mod macros;
pub trait Predicate<C> {
pub trait Predicate<C: Copy> {
fn check(&mut self, chr: C) -> bool;
}
@ -28,29 +28,40 @@ pub trait CollectedSubstring<'source> {
fn compareKeyword<'keyword>(&self, kw: impl Keyword<Self::C>) -> bool;
}
pub enum CollectResult<T> {
EOF,
NotMatches,
Matches(T),
}
pub trait SourceStream<'source, 'pos> {
type C;
type C: Copy;
type P: Pos<'pos>;
type CS: CollectedSubstring<'source, C = Self::C>;
fn skipNext(&mut self, predicate: &mut impl Predicate<Self::C>) -> Option<Self::C>;
fn skipCurrent(
&mut self,
current: Self::C,
predicate: &mut impl Predicate<Self::C>,
) -> Option<Self::C> {
if !predicate.check(current) {
return Some(current);
}
return self.skipNext(predicate);
}
/**
* Returns `true` if the end of stream reached.
* Returns reference to a slice of the source which can be used for comparations
* and exporting (not standardized).
* Also returns char that failed predicate check for further
* interpretation or 'None' if the stream is ended.
*
* Predicate applied to char starting with next after current, assuming that current char
* already checked (you don't call this method in the blind, aren't you).
*
* Calling this method on ended stream (previous `nextChar` returned `None`)
* is undefined behavior.
*/
fn skip(&mut self, predicate: &mut impl Predicate<Self::C>) -> bool;
fn collect(&mut self, predicate: &mut impl Predicate<Self::C>) -> CollectResult<Self::CS>;
fn collect(&mut self, predicate: &mut impl Predicate<Self::C>) -> (Self::CS, Option<Self::C>);
fn pos(&self) -> Self::P;
fn currentChar(&self) -> Option<Self::C>;
fn nextChar(&mut self) -> Option<Self::C>;
fn isEnded(&mut self) -> bool {
return self.currentChar().is_none();
}
}