Fixed ambiguous iterator state when calling first .current() vs .next() and high-level pos counters fix
This commit is contained in:
parent
28d44f907c
commit
04ec6f5acc
@ -1,25 +1,32 @@
|
||||
use crate::iterators::StrSourceIterator;
|
||||
use crate::pos::{NewLinePosCounter, PosLineCol};
|
||||
use crate::pos::{IndexPosCounter, NewLinePosCounter, PosLineCol};
|
||||
use crate::{_CollectScopeContext, SourceIterator};
|
||||
|
||||
#[test]
|
||||
fn sandbox() {
|
||||
let mut z: StrSourceIterator<'_, '_, PosLineCol, NewLinePosCounter> =
|
||||
let mut z: StrSourceIterator<'_, '_, usize, IndexPosCounter> =
|
||||
StrSourceIterator::start("12\n34");
|
||||
println!("{}", z.pos().col);
|
||||
println!("{}", z.pos());
|
||||
z.next();
|
||||
println!("{}", z.pos().col);
|
||||
println!("{} ", z.pos());
|
||||
z.next();
|
||||
println!("{}", z.pos().col);
|
||||
println!("{}", z.pos());
|
||||
z.next();
|
||||
println!("{}", z.pos().col);
|
||||
println!("{} ", z.pos());
|
||||
z.next();
|
||||
println!("{}", z.pos().col);
|
||||
println!("{} ", z.pos());
|
||||
z.next();
|
||||
println!("{}", z.pos().col);
|
||||
println!("{} ", z.pos());
|
||||
z.next();
|
||||
println!("{}", z.pos().col);
|
||||
println!("{} ", z.pos());
|
||||
z.next();
|
||||
println!("{} ", z.pos());
|
||||
z.next();
|
||||
println!("{} ", z.pos());
|
||||
z.next();
|
||||
println!("{} ", z.pos());
|
||||
z.next();
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use source_stream_0::{CollectResult, CollectedSubstring, Pos};
|
||||
|
||||
pub trait PosCounter<'pos, C, P: Pos<'pos>> {
|
||||
fn update(&mut self, c: Option<C>);
|
||||
fn update(&mut self, c: C);
|
||||
|
||||
fn export(&self) -> P;
|
||||
|
||||
@ -9,7 +9,7 @@ pub trait PosCounter<'pos, C, P: Pos<'pos>> {
|
||||
}
|
||||
pub trait _CollectScopeContext<'source, C> {
|
||||
fn next(&mut self) -> Option<C>;
|
||||
fn current(&mut self) -> Option<C>;
|
||||
fn current(&self) -> Option<C>;
|
||||
}
|
||||
|
||||
pub trait SourceIterator<'source, 'pos, C, P: Pos<'pos>, CS: CollectedSubstring<'source, C>>:
|
||||
|
||||
@ -3,12 +3,6 @@ use source_stream_0::{CollectResult, CollectedSubstring, Keyword, KeywordCompara
|
||||
use std::marker::PhantomData;
|
||||
use std::slice::Iter;
|
||||
|
||||
enum _CurrentChar<C> {
|
||||
UNINITIALIZED,
|
||||
EOF,
|
||||
Got(C),
|
||||
}
|
||||
|
||||
pub struct ArrayCollectedSubstring<'source, C> {
|
||||
pub slice: &'source [C],
|
||||
}
|
||||
@ -34,7 +28,7 @@ impl<'source, C: Copy> CollectedSubstring<'source, C> for ArrayCollectedSubstrin
|
||||
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>,
|
||||
_current: Option<&'source C>,
|
||||
_posRaw: usize,
|
||||
_posHighlevel: PC,
|
||||
__phantom1: PhantomData<&'pos ()>,
|
||||
@ -45,10 +39,12 @@ 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> {
|
||||
let mut it = arr.iter();
|
||||
let first = it.next();
|
||||
return ArraySourceIterator {
|
||||
_source: arr,
|
||||
_iter: arr.iter(),
|
||||
_current: _CurrentChar::UNINITIALIZED,
|
||||
_iter: it,
|
||||
_current: first,
|
||||
_posRaw: 0,
|
||||
_posHighlevel: PC::init(),
|
||||
__phantom1: PhantomData::default(),
|
||||
@ -61,32 +57,16 @@ 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);
|
||||
if let Some(c) = self._current {
|
||||
self._posHighlevel.update(*c);
|
||||
self._posRaw += 1;
|
||||
self._current = self._iter.next();
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
return self._current.map(|c| *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),
|
||||
}
|
||||
fn current(&self) -> Option<C> {
|
||||
return self._current.map(|c| *c);
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,10 +84,8 @@ impl<'source, 'pos, C: Copy, P: Pos<'pos>, PC: PosCounter<'pos, C, P>>
|
||||
&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(_) => {}
|
||||
if self._current.is_none() {
|
||||
return CollectResult::EOF;
|
||||
}
|
||||
|
||||
let startPosRaw = self._posRaw;
|
||||
@ -117,9 +95,8 @@ impl<'source, 'pos, C: Copy, P: Pos<'pos>, PC: PosCounter<'pos, C, P>>
|
||||
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],
|
||||
None => slice = &self._source[startPosRaw..],
|
||||
Some(_) => slice = &self._source[startPosRaw..self._posRaw],
|
||||
}
|
||||
return CollectResult::Matches(ArrayCollectedSubstring { slice: slice });
|
||||
}
|
||||
|
||||
@ -3,12 +3,6 @@ use source_stream_0::{CollectResult, CollectedSubstring, Keyword, KeywordCompara
|
||||
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,
|
||||
@ -35,7 +29,7 @@ impl<'source> CollectedSubstring<'source, char> for StrCollectedSubstring<'sourc
|
||||
pub struct StrSourceIterator<'source, 'pos, P: Pos<'pos>, PC: PosCounter<'pos, char, P>> {
|
||||
_source: &'source str,
|
||||
_iter: CharIndices<'source>,
|
||||
_current: _CurrentChar,
|
||||
_current: Option<char>,
|
||||
_posRaw: usize,
|
||||
_posCodePoints: usize,
|
||||
_posHighlevel: PC,
|
||||
@ -47,11 +41,13 @@ 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> {
|
||||
let mut it = s.char_indices();
|
||||
let first = it.next();
|
||||
return StrSourceIterator {
|
||||
_source: s,
|
||||
_iter: s.char_indices(),
|
||||
_current: _CurrentChar::UNINITIALIZED,
|
||||
_posRaw: 0,
|
||||
_iter: it,
|
||||
_current: first.map(|(_, c)| c),
|
||||
_posRaw: first.map_or(s.len(), |(p, _)| p),
|
||||
_posCodePoints: 0,
|
||||
_posHighlevel: PC::init(),
|
||||
__phantom1: PhantomData::default(),
|
||||
@ -64,35 +60,31 @@ impl<'source, 'pos, P: Pos<'pos>, PC: PosCounter<'pos, char, P>> _CollectScopeCo
|
||||
for StrSourceIterator<'source, 'pos, P, PC>
|
||||
{
|
||||
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 => {
|
||||
if let _CurrentChar::Got(_) = self._current {
|
||||
self._posHighlevel.update(None);
|
||||
self._posCodePoints += 1;
|
||||
self._posRaw = self._source.len();
|
||||
}
|
||||
self._current = _CurrentChar::EOF;
|
||||
self._current = None;
|
||||
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);
|
||||
self._current = Some(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),
|
||||
}
|
||||
}
|
||||
|
||||
fn current(&self) -> Option<char> {
|
||||
return self._current;
|
||||
}
|
||||
}
|
||||
|
||||
impl<'source, 'pos, P: Pos<'pos>, PC: PosCounter<'pos, char, P>>
|
||||
@ -109,10 +101,8 @@ impl<'source, 'pos, P: Pos<'pos>, PC: PosCounter<'pos, char, P>>
|
||||
&mut self,
|
||||
scope: impl FnOnce(&mut Self::CollectScopeContext) -> bool,
|
||||
) -> CollectResult<StrCollectedSubstring<'source>> {
|
||||
match self._current {
|
||||
_CurrentChar::EOF => return CollectResult::EOF,
|
||||
_CurrentChar::UNINITIALIZED => {}
|
||||
_CurrentChar::Got(_) => {}
|
||||
if self._current.is_none() {
|
||||
return CollectResult::EOF;
|
||||
}
|
||||
|
||||
let startPosRaw = self._posRaw;
|
||||
@ -123,9 +113,8 @@ impl<'source, 'pos, P: Pos<'pos>, PC: PosCounter<'pos, char, P>>
|
||||
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],
|
||||
None => slice = &self._source[startPosRaw..],
|
||||
Some(_) => slice = &self._source[startPosRaw..self._posRaw],
|
||||
}
|
||||
return CollectResult::Matches(StrCollectedSubstring {
|
||||
slice: slice,
|
||||
|
||||
@ -5,7 +5,7 @@ pub struct IndexPosCounter {
|
||||
}
|
||||
|
||||
impl<C> PosCounter<'static, C, usize> for IndexPosCounter {
|
||||
fn update(&mut self, c: Option<C>) {
|
||||
fn update(&mut self, c: C) {
|
||||
self.index += 1;
|
||||
}
|
||||
|
||||
|
||||
@ -14,19 +14,14 @@ pub struct NewLinePosCounter {
|
||||
}
|
||||
|
||||
impl NewLinePosCounter {
|
||||
pub fn _update<C: PartialEq>(&mut self, actual: Option<C>, expected: C) {
|
||||
match actual {
|
||||
None => {}
|
||||
Some(c) => {
|
||||
if c == expected {
|
||||
pub fn _update<C: PartialEq>(&mut self, actual: C, expected: C) {
|
||||
if actual == expected {
|
||||
self.row += 1;
|
||||
self.col = 0;
|
||||
} else {
|
||||
self.col += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn _export(&self) -> PosLineCol {
|
||||
return PosLineCol {
|
||||
@ -41,7 +36,7 @@ impl NewLinePosCounter {
|
||||
}
|
||||
|
||||
impl PosCounter<'static, char, PosLineCol> for NewLinePosCounter {
|
||||
fn update(&mut self, c: Option<char>) {
|
||||
fn update(&mut self, c: char) {
|
||||
self._update(c, '\n')
|
||||
}
|
||||
|
||||
@ -55,7 +50,7 @@ impl PosCounter<'static, char, PosLineCol> for NewLinePosCounter {
|
||||
}
|
||||
|
||||
impl PosCounter<'static, u8, PosLineCol> for NewLinePosCounter {
|
||||
fn update(&mut self, c: Option<u8>) {
|
||||
fn update(&mut self, c: u8) {
|
||||
self._update(c, b'\n')
|
||||
}
|
||||
|
||||
|
||||
@ -96,7 +96,7 @@ impl<
|
||||
return self._iter.pos();
|
||||
}
|
||||
|
||||
fn currentChar(&mut self) -> Option<C> {
|
||||
fn currentChar(&self) -> Option<C> {
|
||||
return self._iter.current();
|
||||
}
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ pub trait SourceStream<'source, 'pos, C, P: Pos<'pos>, CS: CollectedSubstring<'s
|
||||
|
||||
fn pos(&self) -> P;
|
||||
|
||||
fn currentChar(&mut self) -> Option<C>;
|
||||
fn currentChar(&self) -> Option<C>;
|
||||
fn nextChar(&mut self) -> Option<C>;
|
||||
|
||||
fn isEnded(&mut self) -> bool {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user