Add get_string_until_any_or_rewind function

master
trivernis 4 years ago
parent 3f5cae0eca
commit e316d063f8

@ -1,6 +1,6 @@
[package] [package]
name = "charred" name = "charred"
version = "0.2.0" version = "0.2.1"
authors = ["trivernis <trivernis@protonmail.com>"] authors = ["trivernis <trivernis@protonmail.com>"]
edition = "2018" edition = "2018"
license-file = "LICENSE" license-file = "LICENSE"

@ -3,14 +3,12 @@ use std::fmt::{self, Display, Formatter};
#[derive(Debug)] #[derive(Debug)]
pub struct TapeError { pub struct TapeError {
index: usize index: usize,
} }
impl TapeError { impl TapeError {
pub fn new(index: usize) -> Self { pub fn new(index: usize) -> Self {
Self { Self { index }
index
}
} }
} }
@ -129,7 +127,7 @@ impl CharTapeMachine {
if self.current_char.is_whitespace() { if self.current_char.is_whitespace() {
while let Some(next) = self.next_char() { while let Some(next) = self.next_char() {
if !next.is_whitespace() || self.check_escaped() { if !next.is_whitespace() || self.check_escaped() {
break break;
} }
} }
} }
@ -231,7 +229,11 @@ impl CharTapeMachine {
/// returns an error if the next chars don't match a special sequence /// returns an error if the next chars don't match a special sequence
#[inline] #[inline]
pub fn assert_sequence(&mut self, sequence: &[char], rewind_index: Option<usize>) -> TapeResult<()> { pub fn assert_sequence(
&mut self,
sequence: &[char],
rewind_index: Option<usize>,
) -> TapeResult<()> {
if self.check_sequence(sequence) { if self.check_sequence(sequence) {
Ok(()) Ok(())
} else { } else {
@ -240,7 +242,11 @@ impl CharTapeMachine {
} }
/// returns an error if the next chars don't match any given sequence /// returns an error if the next chars don't match any given sequence
pub fn assert_any_sequence(&mut self, sequences: &[&[char]], rewind_index: Option<usize>) -> TapeResult<()> { pub fn assert_any_sequence(
&mut self,
sequences: &[&[char]],
rewind_index: Option<usize>,
) -> TapeResult<()> {
if self.check_any_sequence(sequences) { if self.check_any_sequence(sequences) {
Ok(()) Ok(())
} else { } else {
@ -250,63 +256,72 @@ impl CharTapeMachine {
/// returns the string until any given character is matched is matched. /// returns the string until any given character is matched is matched.
/// rewinds with error if it encounters a character form the error group /// rewinds with error if it encounters a character form the error group
pub fn get_string_until_any( #[inline]
pub fn get_string_until_any(&mut self, until: &[char], err_at: &[char]) -> TapeResult<String> {
let start_index = self.index;
self.get_string_until_any_or_rewind(until, err_at, start_index)
}
/// Returns the string until it encounters a given sequence or rewinds with error
/// if it encounters an err sequence
pub fn get_string_until_sequence(
&mut self, &mut self,
until: &[char], until: &[&[char]],
err_at: &[char], err_at: &[&[char]],
) -> TapeResult<String> { ) -> Result<String, TapeError> {
let start_index = self.index; let start_index = self.index;
let mut result = String::new(); let mut result = String::new();
if self.check_any(until) { if self.check_any_sequence(until) {
return Ok(result); return Ok(result);
} else if self.check_any(err_at) { } else if self.check_any_sequence(err_at) {
return Err(TapeError::new(self.index)); return Err(TapeError::new(self.index));
} }
result.push(self.current_char); result.push(self.current_char);
while let Some(ch) = self.next_char() { while let Some(ch) = self.next_char() {
if self.check_any(until) || self.check_any(err_at) { if self.check_any_sequence(until) || self.check_any_sequence(err_at) {
break; break;
} }
result.push(ch); result.push(ch);
} }
if self.check_any(err_at) { if self.check_any_sequence(err_at) {
Err(self.rewind_with_error(start_index)) Err(self.rewind_with_error(start_index))
} else { } else {
Ok(result) Ok(result)
} }
} }
/// Returns the string until it encounters a given sequence or rewinds with error /// returns the string until a special char is found
/// if it encounters an err sequence /// or rewinds if an err_at char is found
pub fn get_string_until_sequence( pub fn get_string_until_any_or_rewind(
&mut self, &mut self,
until: &[&[char]], until: &[char],
err_at: &[&[char]], err_at: &[char],
) -> Result<String, TapeError> { rewind_index: usize,
let start_index = self.index; ) -> TapeResult<String> {
let mut result = String::new(); let mut result = String::new();
if self.check_any_sequence(until) { if self.check_any(until) {
return Ok(result); return Ok(result);
} else if self.check_any_sequence(err_at) { } else if self.check_any(err_at) {
return Err(TapeError::new(self.index)); return Err(TapeError::new(self.index));
} }
result.push(self.current_char); result.push(self.current_char);
while let Some(ch) = self.next_char() { while let Some(ch) = self.next_char() {
if self.check_any_sequence(until) || self.check_any_sequence(err_at) { if self.check_any(until) || self.check_any(err_at) {
break; break;
} }
result.push(ch); result.push(ch);
} }
if self.check_any_sequence(err_at) { if self.check_any(err_at) {
Err(self.rewind_with_error(start_index)) Err(self.rewind_with_error(rewind_index))
} else { } else {
Ok(result) Ok(result)
} }
} }
} }

Loading…
Cancel
Save