Default implementations of streams
This commit is contained in:
parent
1545ed40e7
commit
28d44f907c
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,3 +1,3 @@
|
|||||||
/.idea
|
/.idea
|
||||||
/target/*
|
target/
|
||||||
/Cargo.lock
|
Cargo.lock
|
||||||
8
default-streams/Cargo.toml
Normal file
8
default-streams/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "source-stream-0-default-streams-0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
source-stream-0 = { path = ".." }
|
||||||
25
default-streams/src/_sandbox.rs
Normal file
25
default-streams/src/_sandbox.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
use crate::iterators::StrSourceIterator;
|
||||||
|
use crate::pos::{NewLinePosCounter, PosLineCol};
|
||||||
|
use crate::{_CollectScopeContext, SourceIterator};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sandbox() {
|
||||||
|
let mut z: StrSourceIterator<'_, '_, PosLineCol, NewLinePosCounter> =
|
||||||
|
StrSourceIterator::start("12\n34");
|
||||||
|
println!("{}", z.pos().col);
|
||||||
|
z.next();
|
||||||
|
println!("{}", z.pos().col);
|
||||||
|
z.next();
|
||||||
|
println!("{}", z.pos().col);
|
||||||
|
z.next();
|
||||||
|
println!("{}", z.pos().col);
|
||||||
|
z.next();
|
||||||
|
println!("{}", z.pos().col);
|
||||||
|
z.next();
|
||||||
|
println!("{}", z.pos().col);
|
||||||
|
z.next();
|
||||||
|
println!("{}", z.pos().col);
|
||||||
|
z.next();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
26
default-streams/src/iterator.rs
Normal file
26
default-streams/src/iterator.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
use source_stream_0::{CollectResult, CollectedSubstring, Pos};
|
||||||
|
|
||||||
|
pub trait PosCounter<'pos, C, P: Pos<'pos>> {
|
||||||
|
fn update(&mut self, c: Option<C>);
|
||||||
|
|
||||||
|
fn export(&self) -> P;
|
||||||
|
|
||||||
|
fn init() -> Self;
|
||||||
|
}
|
||||||
|
pub trait _CollectScopeContext<'source, C> {
|
||||||
|
fn next(&mut self) -> Option<C>;
|
||||||
|
fn current(&mut self) -> Option<C>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait SourceIterator<'source, 'pos, C, P: Pos<'pos>, CS: CollectedSubstring<'source, C>>:
|
||||||
|
_CollectScopeContext<'source, C>
|
||||||
|
{
|
||||||
|
fn pos(&self) -> P;
|
||||||
|
|
||||||
|
type CollectScopeContext: _CollectScopeContext<'source, C>;
|
||||||
|
|
||||||
|
fn collect(
|
||||||
|
&mut self,
|
||||||
|
scope: impl FnOnce(&mut Self::CollectScopeContext) -> bool,
|
||||||
|
) -> CollectResult<CS>;
|
||||||
|
}
|
||||||
128
default-streams/src/iterators/array.rs
Normal file
128
default-streams/src/iterators/array.rs
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
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 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
default-streams/src/iterators/mod.rs
Normal file
8
default-streams/src/iterators/mod.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
mod str;
|
||||||
|
mod array;
|
||||||
|
|
||||||
|
|
||||||
|
pub use str::StrCollectedSubstring;
|
||||||
|
pub use str::StrSourceIterator;
|
||||||
|
pub use array::ArrayCollectedSubstring;
|
||||||
|
pub use array::ArraySourceIterator;
|
||||||
137
default-streams/src/iterators/str.rs
Normal file
137
default-streams/src/iterators/str.rs
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
use crate::iterator::{_CollectScopeContext, PosCounter, SourceIterator};
|
||||||
|
use source_stream_0::{CollectResult, CollectedSubstring, Keyword, KeywordComparatorIterator, Pos};
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
use std::str::CharIndices;
|
||||||
|
|
||||||
|
enum _CurrentChar {
|
||||||
|
UNINITIALIZED,
|
||||||
|
EOF,
|
||||||
|
Got(char),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct StrCollectedSubstring<'source> {
|
||||||
|
pub slice: &'source str,
|
||||||
|
pub size: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'source> CollectedSubstring<'source, char> for StrCollectedSubstring<'source> {
|
||||||
|
fn compareKeyword<'keyword>(&self, kw: impl Keyword<'keyword, 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, P: Pos<'pos>, PC: PosCounter<'pos, char, P>> {
|
||||||
|
_source: &'source str,
|
||||||
|
_iter: CharIndices<'source>,
|
||||||
|
_current: _CurrentChar,
|
||||||
|
_posRaw: usize,
|
||||||
|
_posCodePoints: usize,
|
||||||
|
_posHighlevel: PC,
|
||||||
|
__phantom1: PhantomData<&'pos ()>,
|
||||||
|
__phantom2: PhantomData<P>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'source, 'pos, P: Pos<'pos>, PC: PosCounter<'pos, char, P>>
|
||||||
|
StrSourceIterator<'source, 'pos, P, PC>
|
||||||
|
{
|
||||||
|
pub fn start(s: &'source str) -> StrSourceIterator<'source, 'pos, P, PC> {
|
||||||
|
return StrSourceIterator {
|
||||||
|
_source: s,
|
||||||
|
_iter: s.char_indices(),
|
||||||
|
_current: _CurrentChar::UNINITIALIZED,
|
||||||
|
_posRaw: 0,
|
||||||
|
_posCodePoints: 0,
|
||||||
|
_posHighlevel: PC::init(),
|
||||||
|
__phantom1: PhantomData::default(),
|
||||||
|
__phantom2: PhantomData::default(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'source, 'pos, P: Pos<'pos>, PC: PosCounter<'pos, char, P>> _CollectScopeContext<'source, char>
|
||||||
|
for StrSourceIterator<'source, 'pos, P, PC>
|
||||||
|
{
|
||||||
|
fn next(&mut self) -> Option<char> {
|
||||||
|
match self._iter.next() {
|
||||||
|
None => {
|
||||||
|
if let _CurrentChar::Got(_) = self._current {
|
||||||
|
self._posHighlevel.update(None);
|
||||||
|
self._posCodePoints += 1;
|
||||||
|
self._posRaw = self._source.len();
|
||||||
|
}
|
||||||
|
self._current = _CurrentChar::EOF;
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some((p, c)) => {
|
||||||
|
self._posRaw = p;
|
||||||
|
if let _CurrentChar::Got(_) = self._current {
|
||||||
|
self._posCodePoints += 1;
|
||||||
|
}
|
||||||
|
self._posHighlevel.update(Some(c));
|
||||||
|
self._current = _CurrentChar::Got(c);
|
||||||
|
return Some(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current(&mut self) -> Option<char> {
|
||||||
|
match self._current {
|
||||||
|
_CurrentChar::UNINITIALIZED => return self.next(),
|
||||||
|
_CurrentChar::EOF => return None,
|
||||||
|
_CurrentChar::Got(c) => return Some(c),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'source, 'pos, P: Pos<'pos>, PC: PosCounter<'pos, char, P>>
|
||||||
|
SourceIterator<'source, 'pos, char, P, StrCollectedSubstring<'source>>
|
||||||
|
for StrSourceIterator<'source, 'pos, P, PC>
|
||||||
|
{
|
||||||
|
fn pos(&self) -> P {
|
||||||
|
return self._posHighlevel.export();
|
||||||
|
}
|
||||||
|
|
||||||
|
type CollectScopeContext = StrSourceIterator<'source, 'pos, P, PC>;
|
||||||
|
|
||||||
|
fn collect(
|
||||||
|
&mut self,
|
||||||
|
scope: impl FnOnce(&mut Self::CollectScopeContext) -> bool,
|
||||||
|
) -> CollectResult<StrCollectedSubstring<'source>> {
|
||||||
|
match self._current {
|
||||||
|
_CurrentChar::EOF => return CollectResult::EOF,
|
||||||
|
_CurrentChar::UNINITIALIZED => {}
|
||||||
|
_CurrentChar::Got(_) => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
let startPosRaw = self._posRaw;
|
||||||
|
let startPosCodePoints = self._posCodePoints;
|
||||||
|
|
||||||
|
match scope(self) {
|
||||||
|
false => return CollectResult::NotMatches,
|
||||||
|
true => {
|
||||||
|
let slice: &'source str;
|
||||||
|
match self._current {
|
||||||
|
_CurrentChar::EOF => slice = &self._source[startPosRaw..],
|
||||||
|
_CurrentChar::UNINITIALIZED => slice = "",
|
||||||
|
_CurrentChar::Got(_) => slice = &self._source[startPosRaw..self._posRaw],
|
||||||
|
}
|
||||||
|
return CollectResult::Matches(StrCollectedSubstring {
|
||||||
|
slice: slice,
|
||||||
|
size: self._posCodePoints - startPosCodePoints,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
default-streams/src/lib.rs
Normal file
11
default-streams/src/lib.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
mod iterator;
|
||||||
|
mod stream;
|
||||||
|
pub use iterator::PosCounter;
|
||||||
|
pub use iterator::SourceIterator;
|
||||||
|
pub use iterator::_CollectScopeContext;
|
||||||
|
pub use stream::SourceStreamOverIterator;
|
||||||
|
|
||||||
|
pub mod pos;
|
||||||
|
pub mod iterators;
|
||||||
|
|
||||||
|
mod _sandbox;
|
||||||
19
default-streams/src/pos/index.rs
Normal file
19
default-streams/src/pos/index.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
use crate::iterator::PosCounter;
|
||||||
|
|
||||||
|
pub struct IndexPosCounter {
|
||||||
|
index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C> PosCounter<'static, C, usize> for IndexPosCounter {
|
||||||
|
fn update(&mut self, c: Option<C>) {
|
||||||
|
self.index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn export(&self) -> usize {
|
||||||
|
return self.index;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init() -> Self {
|
||||||
|
return IndexPosCounter { index: 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
6
default-streams/src/pos/mod.rs
Normal file
6
default-streams/src/pos/mod.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
mod index;
|
||||||
|
mod newline;
|
||||||
|
|
||||||
|
pub use index::IndexPosCounter;
|
||||||
|
pub use newline::PosLineCol;
|
||||||
|
pub use newline::NewLinePosCounter;
|
||||||
69
default-streams/src/pos/newline.rs
Normal file
69
default-streams/src/pos/newline.rs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
use crate::iterator::PosCounter;
|
||||||
|
use source_stream_0::Pos;
|
||||||
|
|
||||||
|
pub struct PosLineCol {
|
||||||
|
pub row: usize,
|
||||||
|
pub col: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Pos<'static> for PosLineCol {}
|
||||||
|
|
||||||
|
pub struct NewLinePosCounter {
|
||||||
|
row: usize,
|
||||||
|
col: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NewLinePosCounter {
|
||||||
|
pub fn _update<C: PartialEq>(&mut self, actual: Option<C>, expected: C) {
|
||||||
|
match actual {
|
||||||
|
None => {}
|
||||||
|
Some(c) => {
|
||||||
|
if c == expected {
|
||||||
|
self.row += 1;
|
||||||
|
self.col = 0;
|
||||||
|
} else {
|
||||||
|
self.col += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _export(&self) -> PosLineCol {
|
||||||
|
return PosLineCol {
|
||||||
|
row: self.row,
|
||||||
|
col: self.col,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _init() -> Self {
|
||||||
|
return NewLinePosCounter { row: 0, col: 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PosCounter<'static, char, PosLineCol> for NewLinePosCounter {
|
||||||
|
fn update(&mut self, c: Option<char>) {
|
||||||
|
self._update(c, '\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
fn export(&self) -> PosLineCol {
|
||||||
|
self._export()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init() -> Self {
|
||||||
|
return NewLinePosCounter::_init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PosCounter<'static, u8, PosLineCol> for NewLinePosCounter {
|
||||||
|
fn update(&mut self, c: Option<u8>) {
|
||||||
|
self._update(c, b'\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
fn export(&self) -> PosLineCol {
|
||||||
|
self._export()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init() -> Self {
|
||||||
|
return NewLinePosCounter::_init();
|
||||||
|
}
|
||||||
|
}
|
||||||
106
default-streams/src/stream.rs
Normal file
106
default-streams/src/stream.rs
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
use crate::iterator::{_CollectScopeContext, SourceIterator};
|
||||||
|
use source_stream_0::{CollectResult, CollectedSubstring, Pos, Predicate, SourceStream};
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
pub struct SourceStreamOverIterator<
|
||||||
|
'source,
|
||||||
|
'pos,
|
||||||
|
C,
|
||||||
|
P: Pos<'pos>,
|
||||||
|
CS: CollectedSubstring<'source, C>,
|
||||||
|
I: SourceIterator<'source, 'pos, C, P, CS>,
|
||||||
|
> {
|
||||||
|
_iter: I,
|
||||||
|
__phantom1: PhantomData<&'source ()>,
|
||||||
|
__phantom2: PhantomData<&'pos ()>,
|
||||||
|
__phantom3: PhantomData<C>,
|
||||||
|
__phantom4: PhantomData<P>,
|
||||||
|
__phantom5: PhantomData<CS>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<
|
||||||
|
'source,
|
||||||
|
'pos,
|
||||||
|
C,
|
||||||
|
P: Pos<'pos>,
|
||||||
|
CS: CollectedSubstring<'source, C>,
|
||||||
|
I: SourceIterator<'source, 'pos, C, P, CS>,
|
||||||
|
> SourceStreamOverIterator<'source, 'pos, C, P, CS, I>
|
||||||
|
{
|
||||||
|
fn wrap(iter: I) -> SourceStreamOverIterator<'source, 'pos, C, P, CS, I> {
|
||||||
|
return SourceStreamOverIterator {
|
||||||
|
_iter: iter,
|
||||||
|
__phantom1: PhantomData::default(),
|
||||||
|
__phantom2: PhantomData::default(),
|
||||||
|
__phantom3: PhantomData::default(),
|
||||||
|
__phantom4: PhantomData::default(),
|
||||||
|
__phantom5: PhantomData::default(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<
|
||||||
|
'source,
|
||||||
|
'pos,
|
||||||
|
C,
|
||||||
|
P: Pos<'pos>,
|
||||||
|
CS: CollectedSubstring<'source, C>,
|
||||||
|
I: SourceIterator<'source, 'pos, C, P, CS>,
|
||||||
|
> SourceStream<'source, 'pos, C, P, CS> for SourceStreamOverIterator<'source, 'pos, C, P, CS, I>
|
||||||
|
{
|
||||||
|
fn skip(&mut self, predicate: &mut impl Predicate<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<C>) -> CollectResult<CS> {
|
||||||
|
return self._iter.collect(|iter| {
|
||||||
|
match iter.current() {
|
||||||
|
Some(c) => match predicate.check(c) {
|
||||||
|
false => return false,
|
||||||
|
true => {}
|
||||||
|
},
|
||||||
|
None => return false,
|
||||||
|
}
|
||||||
|
|
||||||
|
loop {
|
||||||
|
match iter.next() {
|
||||||
|
None => {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Some(c) => match predicate.check(c) {
|
||||||
|
true => continue,
|
||||||
|
false => return true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pos(&self) -> P {
|
||||||
|
return self._iter.pos();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn currentChar(&mut self) -> Option<C> {
|
||||||
|
return self._iter.current();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn nextChar(&mut self) -> Option<C> {
|
||||||
|
return self._iter.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,17 +1,17 @@
|
|||||||
use std::slice::Iter;
|
use std::slice::Iter;
|
||||||
use std::str::Chars;
|
use std::str::Chars;
|
||||||
|
|
||||||
impl crate::_KeywordComparatorIterator<char> for Chars<'_> {
|
impl <'keyword> crate::KeywordComparatorIterator<'keyword, char> for Chars<'keyword> {
|
||||||
fn consume(&mut self, e: char) -> bool {
|
fn consume(&mut self, e: char) -> bool {
|
||||||
return self.next().is_some_and(|a| a == e);
|
return self.next().is_some_and(|a| a == e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::_Keyword<char> for &str {
|
impl <'keyword> crate::Keyword<'keyword, char> for &'keyword str {
|
||||||
fn startComparation(
|
fn startComparation(
|
||||||
&self,
|
&self,
|
||||||
expectedLen: usize,
|
expectedLen: usize,
|
||||||
) -> Option<impl crate::_KeywordComparatorIterator<char>> {
|
) -> Option<impl crate::KeywordComparatorIterator<'keyword, char>> {
|
||||||
if (self.len() != expectedLen) {
|
if (self.len() != expectedLen) {
|
||||||
return Option::None;
|
return Option::None;
|
||||||
}
|
}
|
||||||
@ -20,11 +20,11 @@ impl crate::_Keyword<char> for &str {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::_Keyword<char> for &String {
|
impl <'keyword> crate::Keyword<'keyword, char> for &'keyword String {
|
||||||
fn startComparation(
|
fn startComparation(
|
||||||
&self,
|
&self,
|
||||||
expectedLen: usize,
|
expectedLen: usize,
|
||||||
) -> Option<impl crate::_KeywordComparatorIterator<char>> {
|
) -> Option<impl crate::KeywordComparatorIterator<'keyword, char>> {
|
||||||
if (self.len() != expectedLen) {
|
if (self.len() != expectedLen) {
|
||||||
return Option::None;
|
return Option::None;
|
||||||
}
|
}
|
||||||
@ -32,17 +32,17 @@ impl crate::_Keyword<char> for &String {
|
|||||||
return Option::Some(self.chars());
|
return Option::Some(self.chars());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T: PartialEq> crate::_KeywordComparatorIterator<T> for Iter<'_, T> {
|
impl<'keyword, T: PartialEq> crate::KeywordComparatorIterator<'keyword, T> for Iter<'keyword, T> {
|
||||||
fn consume(&mut self, e: T) -> bool {
|
fn consume(&mut self, e: T) -> bool {
|
||||||
return self.next().is_some_and(|a| a.eq(&e));
|
return self.next().is_some_and(|a| a.eq(&e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PartialEq> crate::_Keyword<T> for &[T] {
|
impl<'keyword, T: PartialEq> crate::Keyword<'keyword, T> for &'keyword [T] {
|
||||||
fn startComparation(
|
fn startComparation(
|
||||||
&self,
|
&self,
|
||||||
expectedLen: usize,
|
expectedLen: usize,
|
||||||
) -> Option<impl crate::_KeywordComparatorIterator<T>> {
|
) -> Option<impl crate::KeywordComparatorIterator<'keyword, T>> {
|
||||||
if (self.len() != expectedLen) {
|
if (self.len() != expectedLen) {
|
||||||
return Option::None;
|
return Option::None;
|
||||||
}
|
}
|
||||||
@ -51,11 +51,11 @@ impl<T: PartialEq> crate::_Keyword<T> for &[T] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PartialEq, const SZ: usize> crate::_Keyword<T> for &[T; SZ] {
|
impl<'keyword, T: PartialEq, const SZ: usize> crate::Keyword<'keyword, T> for &'keyword [T; SZ] {
|
||||||
fn startComparation(
|
fn startComparation(
|
||||||
&self,
|
&self,
|
||||||
expectedLen: usize,
|
expectedLen: usize,
|
||||||
) -> Option<impl crate::_KeywordComparatorIterator<T>> {
|
) -> Option<impl crate::KeywordComparatorIterator<'keyword, T>> {
|
||||||
if (self.len() != expectedLen) {
|
if (self.len() != expectedLen) {
|
||||||
return Option::None;
|
return Option::None;
|
||||||
}
|
}
|
||||||
|
|||||||
35
src/lib.rs
35
src/lib.rs
@ -4,43 +4,44 @@ pub trait Predicate<C> {
|
|||||||
fn check(&mut self, chr: C) -> bool;
|
fn check(&mut self, chr: C) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, F: FnMut(C) -> bool> Predicate<C> for F {
|
pub trait Pos<'pos> {}
|
||||||
fn check(&mut self, chr: C) -> bool {
|
|
||||||
return self(chr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Pos {}
|
impl Pos<'static> for usize {}
|
||||||
|
|
||||||
pub trait _KeywordComparatorIterator<C> {
|
pub trait KeywordComparatorIterator<'keyword, C> {
|
||||||
fn consume(&mut self, c: C) -> bool;
|
fn consume(&mut self, c: C) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait _Keyword<C> {
|
pub trait Keyword<'keyword, C> {
|
||||||
fn startComparation(&self, expectedLen: usize) -> Option<impl _KeywordComparatorIterator<C>>;
|
fn startComparation(
|
||||||
|
&self,
|
||||||
|
expectedLen: usize,
|
||||||
|
) -> Option<impl KeywordComparatorIterator<'keyword, C>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CollectedSubstring<C> {
|
pub trait CollectedSubstring<'source, C> {
|
||||||
fn compareKeyword(&self, kw: impl _Keyword<C>);
|
fn compareKeyword<'keyword>(&self, kw: impl Keyword<'keyword, C>) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum CollectResult<T> {
|
pub enum CollectResult<T> {
|
||||||
EOF,
|
EOF,
|
||||||
NotMatches,
|
NotMatches,
|
||||||
Matches(T)
|
Matches(T),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SourceStream<C, P: Pos, CS: CollectedSubstring<C>> {
|
pub trait SourceStream<'source, 'pos, C, P: Pos<'pos>, CS: CollectedSubstring<'source, C>> {
|
||||||
/**
|
/**
|
||||||
* Returns `true` if the end of stream reached.
|
* Returns `true` if the end of stream reached.
|
||||||
*/
|
*/
|
||||||
fn skip(&mut self, predicate: impl Predicate<C>) -> bool;
|
fn skip(&mut self, predicate: &mut impl Predicate<C>) -> bool;
|
||||||
fn collect(&mut self, predicate: impl Predicate<C>) -> CollectResult<CS>;
|
fn collect(&mut self, predicate: &mut impl Predicate<C>) -> CollectResult<CS>;
|
||||||
|
|
||||||
fn pos(&self) -> P;
|
fn pos(&self) -> P;
|
||||||
|
|
||||||
fn currentChar(&self) -> Option<C>;
|
fn currentChar(&mut self) -> Option<C>;
|
||||||
fn nextChar(&mut self) -> Option<C>;
|
fn nextChar(&mut self) -> Option<C>;
|
||||||
|
|
||||||
fn isEnded(&self) -> bool;
|
fn isEnded(&mut self) -> bool {
|
||||||
|
return self.currentChar().is_none();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user