diff --git a/src/converter/stream.rs b/src/converter/stream.rs index 0e4ef29..4d1cb2e 100644 --- a/src/converter/stream.rs +++ b/src/converter/stream.rs @@ -41,22 +41,18 @@ impl< type P = W::WP; type CS = W::WCS; - fn skipNext(&mut self, predicate: &mut impl Predicate) -> Option { + fn skipNext(&mut self, predicate: &mut impl Predicate) -> bool { return self ._src - .skipNext(&mut PredicateConverter::wrap(predicate, &self._converter)) - .map(|c| self._converter.convertChar(c)); + .skipNext(&mut PredicateConverter::wrap(predicate, &self._converter)); } - fn collect(&mut self, predicate: &mut impl Predicate) -> (Self::CS, Option) { - let (cs, wrongChar) = self + fn collect(&mut self, predicate: &mut impl Predicate) -> Self::CS { + let cs = self ._src .collect(&mut PredicateConverter::wrap(predicate, &self._converter)); - return ( - self._converter.convertSubstring(cs), - wrongChar.map(|c| self._converter.convertChar(c)), - ); + return self._converter.convertSubstring(cs); } fn pos(&self) -> W::WP { @@ -66,4 +62,8 @@ impl< fn nextChar(&mut self) -> Option { return self._src.nextChar().map(|c| self._converter.convertChar(c)); } + + fn currentChar(&self) -> Option { + return self._src.currentChar().map(|c| self._converter.convertChar(c)); + } } diff --git a/src/default_streams/array.rs b/src/default_streams/array.rs index 823f391..39e1c03 100644 --- a/src/default_streams/array.rs +++ b/src/default_streams/array.rs @@ -30,47 +30,35 @@ impl<'source, C: Copy> CollectedSubstring for ArrayCollectedSubstring<'source, C pub struct ArraySourceStream<'source, C: Copy, PC: PosCounter> { _source: &'source [C], __iter: Iter<'source, C>, - _current: C, + _current: Option, _posRaw: usize, _posHighlevel: PC, - _isEnded: bool, } impl<'source, C: Copy, PC: PosCounter> ArraySourceStream<'source, C, PC> { - pub fn start(arr: &'source [C], pos: PC) -> Option<(Self, C)> { + pub fn start(arr: &'source [C], pos: PC) -> Self { 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, - }; - return Some((stream, c)); - } - } + let stream = ArraySourceStream { + _source: arr, + __iter: iter, + _current: first, + _posRaw: 0, + _posHighlevel: pos, + }; + return stream; } } impl<'source, 'pos, C: Copy, PC: PosCounter> ArraySourceStream<'source, C, PC> { fn _next(&mut self) -> Option { - if !self._isEnded { - self._posHighlevel.update(self._current); + if let Some(c) = self._current { + self._posHighlevel.update(c); self._posRaw += 1; } - match self.__iter.next() { - None => return None, - Some(c) => { - self._isEnded = true; - self._current = *c; - return Some(self._current); - } - } + + self._current = self.__iter.next().copied(); + return self._current; } } @@ -79,40 +67,13 @@ impl<'source, C: Copy, PC: PosCounter> SourceStream for ArraySourceStream<'so type P = PC::P; type CS = ArrayCollectedSubstring<'source, C>; - fn skipNext(&mut self, predicate: &mut impl Predicate) -> Option { - loop { - match self._next() { - None => return None, - Some(c) => match predicate.check(c) { - true => continue, - false => return Some(c), - }, - } - } - } - - fn collect(&mut self, predicate: &mut impl Predicate) -> (Self::CS, Option) { + fn collect(&mut self, predicate: &mut impl Predicate) -> Self::CS { let startPosRaw = self._posRaw; - let wrongChar: Option; - loop { - match self._next() { - None => { - wrongChar = None; - break; - } - Some(c) => match predicate.check(c) { - true => continue, - false => { - wrongChar = Some(c); - break; - } - }, - } - } + self.skipNext(predicate); let slice = &self._source[startPosRaw..self._posRaw]; - return (ArrayCollectedSubstring { slice: slice }, wrongChar); + return ArrayCollectedSubstring { slice: slice }; } fn pos(&self) -> Self::P { @@ -122,4 +83,8 @@ impl<'source, C: Copy, PC: PosCounter> SourceStream for ArraySourceStream<'so fn nextChar(&mut self) -> Option { return self._next(); } + + fn currentChar(&self) -> Option { + return self._current; + } } diff --git a/src/default_streams/empty.rs b/src/default_streams/empty.rs index 04af898..c742ae0 100644 --- a/src/default_streams/empty.rs +++ b/src/default_streams/empty.rs @@ -1,16 +1,18 @@ -use std::marker::PhantomData; -use crate::pos::{PosCounter}; +use crate::pos::PosCounter; use crate::{CollectedSubstring, Predicate, SourceStream}; +use std::marker::PhantomData; pub struct EmptySourceStream, PC: PosCounter> { _pos: PC, - __phantom: PhantomData<(C, CS)> + __phantom: PhantomData<(C, CS)>, } impl, PC: PosCounter> EmptySourceStream { - pub fn start(pos: PC) -> (Self, Option) { - let stream = EmptySourceStream { _pos: pos, __phantom: PhantomData::default() }; - return (stream, None); + pub fn start(pos: PC) -> Self { + return EmptySourceStream { + _pos: pos, + __phantom: PhantomData::default(), + }; } } @@ -21,11 +23,15 @@ impl, PC: PosCounter> SourceStream type P = PC::P; type CS = CS; - fn skipNext(&mut self, _: &mut impl Predicate) -> Option { - return None; + fn skipCurrent(&mut self, _: &mut impl Predicate) -> bool { + return true; } - fn collect(&mut self, _: &mut impl Predicate) -> (Self::CS, Option) { + fn skipNext(&mut self, _: &mut impl Predicate) -> bool { + return true; + } + + fn collect(&mut self, _: &mut impl Predicate) -> Self::CS { panic!("How about to check first char of substring being collected first"); } @@ -36,4 +42,8 @@ impl, PC: PosCounter> SourceStream fn nextChar(&mut self) -> Option { return None; } + + fn currentChar(&self) -> Option { + return None; + } } diff --git a/src/default_streams/str.rs b/src/default_streams/str.rs index cd15ca3..ae99237 100644 --- a/src/default_streams/str.rs +++ b/src/default_streams/str.rs @@ -31,50 +31,55 @@ impl<'source> CollectedSubstring for StrCollectedSubstring<'source> { pub struct StrSourceStream<'source, PC: PosCounter> { _source: &'source str, __iter: CharIndices<'source>, - _current: char, + _current: Option, _posRaw: usize, _posCodePoints: usize, _posHighlevel: PC, - _isEnded: bool, } impl<'source, PC: PosCounter> StrSourceStream<'source, PC> { - pub fn start(s: &'source str, pos: PC) -> Option<(Self, char)> { + pub fn start(s: &'source str, pos: PC) -> Self { let mut it = s.char_indices(); let first = it.next(); + + let mut stream = StrSourceStream { + _source: s, + __iter: it, + _current: None, + _posRaw: s.len(), + _posCodePoints: 0, + _posHighlevel: pos, + }; + match first { - None => return None, + None => {} Some((p, c)) => { - let stream = StrSourceStream { - _source: s, - __iter: it, - _current: c, - _posRaw: p, - _posCodePoints: 0, - _posHighlevel: pos, - _isEnded: false, - }; - return Some((stream, c)); + stream._current = Some(c); + stream._posRaw = p } } + return stream; } } impl<'source, PC: PosCounter> StrSourceStream<'source, PC> { fn _next(&mut self) -> Option { - if !self._isEnded { - self._posHighlevel.update(self._current); + if let Some(c) = self._current { + self._posHighlevel.update(c); self._posCodePoints += 1; } + match self.__iter.next() { - None => return None, + None => { + self._posRaw = self._source.len(); + self._current = None; + } Some((p, c)) => { - self._isEnded = true; self._posRaw = p; - self._current = c; - return Some(self._current); + self._current = Some(c); } } + return self._current; } } @@ -83,47 +88,17 @@ impl<'source, PC: PosCounter> SourceStream for StrSourceStream<'source, PC type P = PC::P; type CS = StrCollectedSubstring<'source>; - fn skipNext(&mut self, predicate: &mut impl Predicate) -> Option { - loop { - match self._next() { - None => return None, - Some(c) => match predicate.check(c) { - true => continue, - false => return Some(c), - }, - } - } - } - - fn collect(&mut self, predicate: &mut impl Predicate) -> (Self::CS, Option) { + fn collect(&mut self, predicate: &mut impl Predicate) -> Self::CS { let startPosRaw = self._posRaw; let startPosCP = self._posCodePoints; - - let wrongChar: Option; - loop { - match self._next() { - None => { - wrongChar = None; - break; - } - Some(c) => match predicate.check(c) { - true => continue, - false => { - wrongChar = Some(c); - break; - } - }, - } - } - + + self.skipNext(predicate); + let slice = &self._source[startPosRaw..self._posRaw]; - return ( - StrCollectedSubstring { - slice: slice, - size: self._posCodePoints - startPosCP, - }, - wrongChar, - ); + return StrCollectedSubstring { + slice: slice, + size: self._posCodePoints - startPosCP, + }; } fn pos(&self) -> Self::P { @@ -133,4 +108,8 @@ impl<'source, PC: PosCounter> SourceStream for StrSourceStream<'source, PC fn nextChar(&mut self) -> Option { return self._next(); } + + fn currentChar(&self) -> Option { + return self._current; + } } diff --git a/src/stream.rs b/src/stream.rs index 3fc10f8..880e01a 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -10,18 +10,32 @@ pub trait SourceStream { type P: Pos; type CS: CollectedSubstring; - fn skipNext(&mut self, predicate: &mut impl Predicate) -> Option; - fn skipCurrent( &mut self, - current: Self::C, predicate: &mut impl Predicate, - ) -> Option { - if !predicate.check(current) { - return Some(current); + ) -> bool { + match self.currentChar() { + None => return true, + Some(c) => { + if !predicate.check(c) { + return false; + } + + return self.skipNext(predicate); + } } + } - return self.skipNext(predicate); + fn skipNext(&mut self, predicate: &mut impl Predicate) -> bool { + loop { + match self.nextChar() { + None => return true, + Some(c) => match predicate.check(c) { + true => continue, + false => return false, + }, + } + } } /** @@ -36,9 +50,11 @@ pub trait SourceStream { * Calling this method on ended stream (previous `nextChar` returned `None`) * is undefined behavior. */ - fn collect(&mut self, predicate: &mut impl Predicate) -> (Self::CS, Option); + fn collect(&mut self, predicate: &mut impl Predicate) -> Self::CS; fn pos(&self) -> Self::P; fn nextChar(&mut self) -> Option; + + fn currentChar(&self) -> Option; }