Redesigned source stream to fold same checks and increase performance
This commit is contained in:
parent
11541e9396
commit
1200f99e38
@ -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(),
|
||||
));
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
_source: arr,
|
||||
_iter: it,
|
||||
_current: first,
|
||||
_posRaw: 0,
|
||||
_posHighlevel: pos,
|
||||
__phantom: PhantomData::default(),
|
||||
};
|
||||
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: 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();
|
||||
}
|
||||
}
|
||||
|
||||
62
default-streams/src/iterators/empty.rs
Normal file
62
default-streams/src/iterators/empty.rs
Normal 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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
@ -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 {
|
||||
_source: s,
|
||||
_iter: it,
|
||||
_current: first.map(|(_, c)| c),
|
||||
_posRaw: first.map_or(s.len(), |(p, _)| p),
|
||||
_posCodePoints: 0,
|
||||
_posHighlevel: pos,
|
||||
__phantom: PhantomData::default(),
|
||||
};
|
||||
match first {
|
||||
None => return None,
|
||||
Some((p, c)) => {
|
||||
let stream = StrSourceStream {
|
||||
_source: s,
|
||||
__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 {
|
||||
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 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),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn current(&self) -> Option<char> {
|
||||
return self._current;
|
||||
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 => {
|
||||
wrongChar = None;
|
||||
break;
|
||||
}
|
||||
Some(c) => match predicate.check(c) {
|
||||
true => continue,
|
||||
false => {
|
||||
wrongChar = Some(c);
|
||||
break;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
@ -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) {
|
||||
|
||||
@ -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) {}
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
45
src/lib.rs
45
src/lib.rs
@ -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>;
|
||||
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();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user