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::iterators::StrSourceIterator;
|
||||||
use crate::pos::{NewLinePosCounter, PosLineCol};
|
use crate::pos::{IndexPosCounter, NewLinePosCounter, PosLineCol};
|
||||||
use crate::{_CollectScopeContext, SourceIterator};
|
use crate::{_CollectScopeContext, SourceIterator};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sandbox() {
|
fn sandbox() {
|
||||||
let mut z: StrSourceIterator<'_, '_, PosLineCol, NewLinePosCounter> =
|
let mut z: StrSourceIterator<'_, '_, usize, IndexPosCounter> =
|
||||||
StrSourceIterator::start("12\n34");
|
StrSourceIterator::start("12\n34");
|
||||||
println!("{}", z.pos().col);
|
println!("{}", z.pos());
|
||||||
z.next();
|
z.next();
|
||||||
println!("{}", z.pos().col);
|
println!("{} ", z.pos());
|
||||||
z.next();
|
z.next();
|
||||||
println!("{}", z.pos().col);
|
println!("{}", z.pos());
|
||||||
z.next();
|
z.next();
|
||||||
println!("{}", z.pos().col);
|
println!("{} ", z.pos());
|
||||||
z.next();
|
z.next();
|
||||||
println!("{}", z.pos().col);
|
println!("{} ", z.pos());
|
||||||
z.next();
|
z.next();
|
||||||
println!("{}", z.pos().col);
|
println!("{} ", z.pos());
|
||||||
z.next();
|
z.next();
|
||||||
println!("{}", z.pos().col);
|
println!("{} ", z.pos());
|
||||||
z.next();
|
z.next();
|
||||||
|
println!("{} ", z.pos());
|
||||||
|
z.next();
|
||||||
|
println!("{} ", z.pos());
|
||||||
|
z.next();
|
||||||
|
println!("{} ", z.pos());
|
||||||
|
z.next();
|
||||||
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use source_stream_0::{CollectResult, CollectedSubstring, Pos};
|
use source_stream_0::{CollectResult, CollectedSubstring, Pos};
|
||||||
|
|
||||||
pub trait PosCounter<'pos, C, P: Pos<'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;
|
fn export(&self) -> P;
|
||||||
|
|
||||||
@ -9,7 +9,7 @@ pub trait PosCounter<'pos, C, P: Pos<'pos>> {
|
|||||||
}
|
}
|
||||||
pub trait _CollectScopeContext<'source, C> {
|
pub trait _CollectScopeContext<'source, C> {
|
||||||
fn next(&mut self) -> Option<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>>:
|
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::marker::PhantomData;
|
||||||
use std::slice::Iter;
|
use std::slice::Iter;
|
||||||
|
|
||||||
enum _CurrentChar<C> {
|
|
||||||
UNINITIALIZED,
|
|
||||||
EOF,
|
|
||||||
Got(C),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ArrayCollectedSubstring<'source, C> {
|
pub struct ArrayCollectedSubstring<'source, C> {
|
||||||
pub slice: &'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>> {
|
pub struct ArraySourceIterator<'source, 'pos, C: Copy, P: Pos<'pos>, PC: PosCounter<'pos, C, P>> {
|
||||||
_source: &'source [C],
|
_source: &'source [C],
|
||||||
_iter: Iter<'source, C>,
|
_iter: Iter<'source, C>,
|
||||||
_current: _CurrentChar<&'source C>,
|
_current: Option<&'source C>,
|
||||||
_posRaw: usize,
|
_posRaw: usize,
|
||||||
_posHighlevel: PC,
|
_posHighlevel: PC,
|
||||||
__phantom1: PhantomData<&'pos ()>,
|
__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>
|
ArraySourceIterator<'source, 'pos, C, P, PC>
|
||||||
{
|
{
|
||||||
pub fn start(arr: &'source [C]) -> 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 {
|
return ArraySourceIterator {
|
||||||
_source: arr,
|
_source: arr,
|
||||||
_iter: arr.iter(),
|
_iter: it,
|
||||||
_current: _CurrentChar::UNINITIALIZED,
|
_current: first,
|
||||||
_posRaw: 0,
|
_posRaw: 0,
|
||||||
_posHighlevel: PC::init(),
|
_posHighlevel: PC::init(),
|
||||||
__phantom1: PhantomData::default(),
|
__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>
|
_CollectScopeContext<'source, C> for ArraySourceIterator<'source, 'pos, C, P, PC>
|
||||||
{
|
{
|
||||||
fn next(&mut self) -> Option<C> {
|
fn next(&mut self) -> Option<C> {
|
||||||
match self._iter.next() {
|
if let Some(c) = self._current {
|
||||||
None => {
|
self._posHighlevel.update(*c);
|
||||||
if let _CurrentChar::Got(_) = self._current {
|
|
||||||
self._posHighlevel.update(None);
|
|
||||||
self._posRaw += 1;
|
self._posRaw += 1;
|
||||||
|
self._current = self._iter.next();
|
||||||
}
|
}
|
||||||
self._current = _CurrentChar::EOF;
|
return self._current.map(|c| *c);
|
||||||
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> {
|
fn current(&self) -> Option<C> {
|
||||||
match self._current {
|
return self._current.map(|c| *c);
|
||||||
_CurrentChar::UNINITIALIZED => return self.next(),
|
|
||||||
_CurrentChar::EOF => return None,
|
|
||||||
_CurrentChar::Got(c) => return Some(*c),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,10 +84,8 @@ impl<'source, 'pos, C: Copy, P: Pos<'pos>, PC: PosCounter<'pos, C, P>>
|
|||||||
&mut self,
|
&mut self,
|
||||||
scope: impl FnOnce(&mut Self::CollectScopeContext) -> bool,
|
scope: impl FnOnce(&mut Self::CollectScopeContext) -> bool,
|
||||||
) -> CollectResult<ArrayCollectedSubstring<'source, C>> {
|
) -> CollectResult<ArrayCollectedSubstring<'source, C>> {
|
||||||
match self._current {
|
if self._current.is_none() {
|
||||||
_CurrentChar::EOF => return CollectResult::EOF,
|
return CollectResult::EOF;
|
||||||
_CurrentChar::UNINITIALIZED => {}
|
|
||||||
_CurrentChar::Got(_) => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let startPosRaw = self._posRaw;
|
let startPosRaw = self._posRaw;
|
||||||
@ -117,9 +95,8 @@ impl<'source, 'pos, C: Copy, P: Pos<'pos>, PC: PosCounter<'pos, C, P>>
|
|||||||
true => {
|
true => {
|
||||||
let slice: &'source [C];
|
let slice: &'source [C];
|
||||||
match self._current {
|
match self._current {
|
||||||
_CurrentChar::EOF => slice = &self._source[startPosRaw..],
|
None => slice = &self._source[startPosRaw..],
|
||||||
_CurrentChar::UNINITIALIZED => slice = &[],
|
Some(_) => slice = &self._source[startPosRaw..self._posRaw],
|
||||||
_CurrentChar::Got(_) => slice = &self._source[startPosRaw..self._posRaw],
|
|
||||||
}
|
}
|
||||||
return CollectResult::Matches(ArrayCollectedSubstring { slice: slice });
|
return CollectResult::Matches(ArrayCollectedSubstring { slice: slice });
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,12 +3,6 @@ use source_stream_0::{CollectResult, CollectedSubstring, Keyword, KeywordCompara
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::str::CharIndices;
|
use std::str::CharIndices;
|
||||||
|
|
||||||
enum _CurrentChar {
|
|
||||||
UNINITIALIZED,
|
|
||||||
EOF,
|
|
||||||
Got(char),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct StrCollectedSubstring<'source> {
|
pub struct StrCollectedSubstring<'source> {
|
||||||
pub slice: &'source str,
|
pub slice: &'source str,
|
||||||
pub size: usize,
|
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>> {
|
pub struct StrSourceIterator<'source, 'pos, P: Pos<'pos>, PC: PosCounter<'pos, char, P>> {
|
||||||
_source: &'source str,
|
_source: &'source str,
|
||||||
_iter: CharIndices<'source>,
|
_iter: CharIndices<'source>,
|
||||||
_current: _CurrentChar,
|
_current: Option<char>,
|
||||||
_posRaw: usize,
|
_posRaw: usize,
|
||||||
_posCodePoints: usize,
|
_posCodePoints: usize,
|
||||||
_posHighlevel: PC,
|
_posHighlevel: PC,
|
||||||
@ -47,11 +41,13 @@ impl<'source, 'pos, P: Pos<'pos>, PC: PosCounter<'pos, char, P>>
|
|||||||
StrSourceIterator<'source, 'pos, P, PC>
|
StrSourceIterator<'source, 'pos, P, PC>
|
||||||
{
|
{
|
||||||
pub fn start(s: &'source str) -> 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 {
|
return StrSourceIterator {
|
||||||
_source: s,
|
_source: s,
|
||||||
_iter: s.char_indices(),
|
_iter: it,
|
||||||
_current: _CurrentChar::UNINITIALIZED,
|
_current: first.map(|(_, c)| c),
|
||||||
_posRaw: 0,
|
_posRaw: first.map_or(s.len(), |(p, _)| p),
|
||||||
_posCodePoints: 0,
|
_posCodePoints: 0,
|
||||||
_posHighlevel: PC::init(),
|
_posHighlevel: PC::init(),
|
||||||
__phantom1: PhantomData::default(),
|
__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>
|
for StrSourceIterator<'source, 'pos, P, PC>
|
||||||
{
|
{
|
||||||
fn next(&mut self) -> Option<char> {
|
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() {
|
match self._iter.next() {
|
||||||
None => {
|
None => {
|
||||||
if let _CurrentChar::Got(_) = self._current {
|
|
||||||
self._posHighlevel.update(None);
|
|
||||||
self._posCodePoints += 1;
|
|
||||||
self._posRaw = self._source.len();
|
self._posRaw = self._source.len();
|
||||||
}
|
self._current = None;
|
||||||
self._current = _CurrentChar::EOF;
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Some((p, c)) => {
|
Some((p, c)) => {
|
||||||
self._posRaw = p;
|
self._posRaw = p;
|
||||||
if let _CurrentChar::Got(_) = self._current {
|
self._current = Some(c);
|
||||||
self._posCodePoints += 1;
|
|
||||||
}
|
|
||||||
self._posHighlevel.update(Some(c));
|
|
||||||
self._current = _CurrentChar::Got(c);
|
|
||||||
return 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>>
|
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,
|
&mut self,
|
||||||
scope: impl FnOnce(&mut Self::CollectScopeContext) -> bool,
|
scope: impl FnOnce(&mut Self::CollectScopeContext) -> bool,
|
||||||
) -> CollectResult<StrCollectedSubstring<'source>> {
|
) -> CollectResult<StrCollectedSubstring<'source>> {
|
||||||
match self._current {
|
if self._current.is_none() {
|
||||||
_CurrentChar::EOF => return CollectResult::EOF,
|
return CollectResult::EOF;
|
||||||
_CurrentChar::UNINITIALIZED => {}
|
|
||||||
_CurrentChar::Got(_) => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let startPosRaw = self._posRaw;
|
let startPosRaw = self._posRaw;
|
||||||
@ -123,9 +113,8 @@ impl<'source, 'pos, P: Pos<'pos>, PC: PosCounter<'pos, char, P>>
|
|||||||
true => {
|
true => {
|
||||||
let slice: &'source str;
|
let slice: &'source str;
|
||||||
match self._current {
|
match self._current {
|
||||||
_CurrentChar::EOF => slice = &self._source[startPosRaw..],
|
None => slice = &self._source[startPosRaw..],
|
||||||
_CurrentChar::UNINITIALIZED => slice = "",
|
Some(_) => slice = &self._source[startPosRaw..self._posRaw],
|
||||||
_CurrentChar::Got(_) => slice = &self._source[startPosRaw..self._posRaw],
|
|
||||||
}
|
}
|
||||||
return CollectResult::Matches(StrCollectedSubstring {
|
return CollectResult::Matches(StrCollectedSubstring {
|
||||||
slice: slice,
|
slice: slice,
|
||||||
|
|||||||
@ -5,7 +5,7 @@ pub struct IndexPosCounter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<C> PosCounter<'static, C, usize> for 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;
|
self.index += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,19 +14,14 @@ pub struct NewLinePosCounter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl NewLinePosCounter {
|
impl NewLinePosCounter {
|
||||||
pub fn _update<C: PartialEq>(&mut self, actual: Option<C>, expected: C) {
|
pub fn _update<C: PartialEq>(&mut self, actual: C, expected: C) {
|
||||||
match actual {
|
if actual == expected {
|
||||||
None => {}
|
|
||||||
Some(c) => {
|
|
||||||
if c == expected {
|
|
||||||
self.row += 1;
|
self.row += 1;
|
||||||
self.col = 0;
|
self.col = 0;
|
||||||
} else {
|
} else {
|
||||||
self.col += 1;
|
self.col += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn _export(&self) -> PosLineCol {
|
pub fn _export(&self) -> PosLineCol {
|
||||||
return PosLineCol {
|
return PosLineCol {
|
||||||
@ -41,7 +36,7 @@ impl NewLinePosCounter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PosCounter<'static, char, PosLineCol> for 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')
|
self._update(c, '\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +50,7 @@ impl PosCounter<'static, char, PosLineCol> for NewLinePosCounter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PosCounter<'static, u8, 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')
|
self._update(c, b'\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -96,7 +96,7 @@ impl<
|
|||||||
return self._iter.pos();
|
return self._iter.pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn currentChar(&mut self) -> Option<C> {
|
fn currentChar(&self) -> Option<C> {
|
||||||
return self._iter.current();
|
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 pos(&self) -> P;
|
||||||
|
|
||||||
fn currentChar(&mut self) -> Option<C>;
|
fn currentChar(&self) -> Option<C>;
|
||||||
fn nextChar(&mut self) -> Option<C>;
|
fn nextChar(&mut self) -> Option<C>;
|
||||||
|
|
||||||
fn isEnded(&mut self) -> bool {
|
fn isEnded(&mut self) -> bool {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user