Implement Copy for ReaderState.

This commit is contained in:
jcamiel 2023-11-24 17:59:17 +01:00
parent bf8deaf1cd
commit 4fbbb6d683
No known key found for this signature in database
GPG Key ID: 07FF11CFD55356CC
18 changed files with 106 additions and 107 deletions

View File

@ -70,11 +70,11 @@ pub fn eval_json_value(
// The String can only be null, a bool, a number
// It will be easier when your variables value have a type
let mut reader = Reader::new(s.as_str());
let start = reader.state.clone();
let start = reader.state;
if parse_json_number(&mut reader).is_ok() {
return Ok(s);
}
reader.state = start.clone();
reader.state = start;
if parse_json_boolean(&mut reader).is_ok() {
return Ok(s);
}

View File

@ -31,7 +31,7 @@ pub fn parse(reader: &mut Reader) -> Vec<u8> {
if !pad.is_empty() {
break;
}
let save = reader.state.clone();
let save = reader.state;
match reader.read() {
None => {
break;
@ -142,7 +142,7 @@ fn padding(reader: &mut Reader) -> String {
// consume padding can not fail
let mut buf = String::new();
loop {
let save = reader.state.clone();
let save = reader.state;
match reader.read() {
Some('=') => {
buf.push('=');

View File

@ -20,7 +20,7 @@ use crate::parser::reader::Reader;
use crate::parser::{ParseFunc, ParseResult};
pub fn optional<T>(f: ParseFunc<T>, reader: &mut Reader) -> ParseResult<Option<T>> {
let start = reader.state.clone();
let start = reader.state;
match f(reader) {
Ok(r) => Ok(Some(r)),
Err(e) => {
@ -59,11 +59,11 @@ pub fn nonrecover<T>(f: ParseFunc<T>, reader: &mut Reader) -> ParseResult<T> {
}
pub fn zero_or_more<T>(f: ParseFunc<T>, reader: &mut Reader) -> ParseResult<Vec<T>> {
let _start = reader.state.clone();
let _start = reader.state;
let mut v: Vec<T> = Vec::new();
loop {
let initial_state = reader.state.clone();
let initial_state = reader.state;
if reader.is_eof() {
return Ok(v);
}
@ -86,12 +86,12 @@ pub fn zero_or_more<T>(f: ParseFunc<T>, reader: &mut Reader) -> ParseResult<Vec<
}
pub fn one_or_more<T>(f: ParseFunc<T>, reader: &mut Reader) -> ParseResult<Vec<T>> {
let _initial_state = reader.state.clone();
let _initial_state = reader.state;
match f(reader) {
Ok(first) => {
let mut v = vec![first];
loop {
let initial_state = reader.state.clone();
let initial_state = reader.state;
match f(reader) {
Ok(r) => {
v.push(r);
@ -123,7 +123,7 @@ pub fn one_or_more<T>(f: ParseFunc<T>, reader: &mut Reader) -> ParseResult<Vec<T
/// Typically this should be recoverable
pub fn choice<T>(fs: &[ParseFunc<T>], reader: &mut Reader) -> ParseResult<T> {
for (pos, f) in fs.iter().enumerate() {
let start = reader.state.clone();
let start = reader.state;
if pos == fs.len() - 1 {
return f(reader);
}

View File

@ -56,7 +56,7 @@ pub fn parse2(reader: &mut Reader) -> ParseResult<Expr> {
}
fn variable_name(reader: &mut Reader) -> ParseResult<Variable> {
let start = reader.state.clone();
let start = reader.state;
let name = reader.read_while(|c| c.is_alphanumeric() || *c == '_' || *c == '-');
if name.is_empty() {
return Err(Error {

View File

@ -24,7 +24,7 @@ pub fn parse(reader: &mut Reader) -> ParseResult<Filename> {
// This is an absolute file
// that you have to write with a relative name
// default root_dir is the hurl directory
let start = reader.state.clone();
let start = reader.state;
let s = reader.read_while_escaping(|c| {
c.is_alphanumeric() || *c == '.' || *c == '/' || *c == '_' || *c == '-'
});
@ -40,7 +40,7 @@ pub fn parse(reader: &mut Reader) -> ParseResult<Filename> {
value: s,
source_info: SourceInfo {
start: start.pos,
end: reader.state.clone().pos,
end: reader.state.pos,
},
})
}

View File

@ -25,7 +25,7 @@ use crate::parser::{Error, ParseError, ParseResult, Reader};
pub fn filters(reader: &mut Reader) -> ParseResult<Vec<(Whitespace, Filter)>> {
let mut filters = vec![];
loop {
let save = reader.state.clone();
let save = reader.state;
let space = zero_or_more_spaces(reader)?;
if space.value.is_empty() {
break;

View File

@ -116,12 +116,12 @@ fn string_template(reader: &mut Reader) -> ParseResult<Template> {
}
fn any_char(reader: &mut Reader) -> ParseResult<(char, String, Pos)> {
let start = reader.state.clone();
let start = reader.state;
match escape_char(reader) {
Ok(c) => Ok((c, reader.peek_back(start.cursor), start.pos)),
Err(e) => {
if e.recoverable {
reader.state = start.clone();
reader.state = start;
match reader.read() {
None => Err(error::Error {
pos: start.pos,
@ -153,7 +153,7 @@ fn any_char(reader: &mut Reader) -> ParseResult<(char, String, Pos)> {
fn escape_char(reader: &mut Reader) -> ParseResult<char> {
try_literal("\\", reader)?;
let start = reader.state.clone();
let start = reader.state;
match reader.read() {
Some('"') => Ok('"'),
Some('\\') => Ok('\\'),
@ -197,7 +197,7 @@ fn hex_value(reader: &mut Reader) -> ParseResult<u32> {
}
pub fn number_value(reader: &mut Reader) -> ParseResult<JsonValue> {
let start = reader.state.clone();
let start = reader.state;
let sign = match try_literal("-", reader) {
Err(_) => String::new(),
@ -360,7 +360,7 @@ pub fn object_value(reader: &mut Reader) -> ParseResult<JsonValue> {
}
fn key(reader: &mut Reader) -> ParseResult<Template> {
let save = reader.state.clone();
let save = reader.state;
let name = string_template(reader).map_err(|e| e.non_recoverable())?;
if name.elements.is_empty() {
Err(error::Error {

View File

@ -23,7 +23,7 @@ use crate::parser::template::template;
use crate::parser::{string, ParseResult};
pub fn parse(reader: &mut Reader) -> ParseResult<Template> {
let start = reader.state.clone();
let start = reader.state;
let mut elements = vec![];
loop {
@ -70,7 +70,7 @@ pub fn parse(reader: &mut Reader) -> ParseResult<Template> {
}
}
let end = reader.state.clone();
let end = reader.state;
Ok(Template {
delimiter: None,
elements,
@ -108,7 +108,7 @@ fn key_string_content(reader: &mut Reader) -> ParseResult<String> {
fn key_string_text(reader: &mut Reader) -> String {
let mut s = String::new();
loop {
let save = reader.state.clone();
let save = reader.state;
match reader.read() {
None => break,
Some(c) => {
@ -135,7 +135,7 @@ fn key_string_text(reader: &mut Reader) -> String {
fn key_string_escaped_char(reader: &mut Reader) -> ParseResult<char> {
try_literal("\\", reader)?;
let start = reader.state.clone();
let start = reader.state;
match reader.read() {
Some('#') => Ok('#'),
Some(':') => Ok(':'),

View File

@ -24,7 +24,7 @@ use crate::parser::{template, Error, ParseError, ParseResult};
pub fn multiline_string(reader: &mut Reader) -> ParseResult<MultilineString> {
try_literal("```", reader)?;
let save = reader.state.clone();
let save = reader.state;
match choice(&[json_text, xml_text, graphql, plain_text], reader) {
Ok(multi) => Ok(multi),
@ -141,7 +141,7 @@ fn graphql(reader: &mut Reader) -> ParseResult<MultilineString> {
}
fn whitespace(reader: &mut Reader) -> ParseResult<Whitespace> {
let start = reader.state.clone();
let start = reader.state;
match reader.read() {
None => Err(Error {
pos: start.pos,
@ -171,7 +171,7 @@ fn whitespace(reader: &mut Reader) -> ParseResult<Whitespace> {
}
fn zero_or_more_whitespaces(reader: &mut Reader) -> ParseResult<Whitespace> {
let start = reader.state.clone();
let start = reader.state;
match zero_or_more(whitespace, reader) {
Ok(v) => {
let s = v.iter().map(|x| x.value.clone()).collect();
@ -192,7 +192,7 @@ fn zero_or_more_whitespaces(reader: &mut Reader) -> ParseResult<Whitespace> {
fn graphql_variables(reader: &mut Reader) -> ParseResult<GraphQlVariables> {
try_literal("variables", reader)?;
let space = zero_or_more_spaces(reader)?;
let start = reader.state.clone();
let start = reader.state;
let object = object_value(reader);
let value = match object {
Ok(obj) => obj,

View File

@ -224,7 +224,7 @@ fn retry(reader: &mut Reader) -> ParseResult<Retry> {
}
fn boolean_option(reader: &mut Reader) -> ParseResult<BooleanOption> {
let start = reader.state.clone();
let start = reader.state;
match boolean(reader) {
Ok(v) => Ok(BooleanOption::Literal(v)),
Err(_) => {
@ -242,7 +242,7 @@ fn boolean_option(reader: &mut Reader) -> ParseResult<BooleanOption> {
}
fn natural_option(reader: &mut Reader) -> ParseResult<NaturalOption> {
let start = reader.state.clone();
let start = reader.state;
match natural(reader) {
Ok(v) => Ok(NaturalOption::Literal(v)),
Err(_) => {
@ -260,7 +260,7 @@ fn natural_option(reader: &mut Reader) -> ParseResult<NaturalOption> {
}
fn retry_option(reader: &mut Reader) -> ParseResult<RetryOption> {
let start = reader.state.clone();
let start = reader.state;
match retry(reader) {
Ok(v) => Ok(RetryOption::Literal(v)),
Err(_) => {
@ -292,7 +292,7 @@ fn variable_definition(reader: &mut Reader) -> ParseResult<VariableDefinition> {
}
fn variable_name(reader: &mut Reader) -> ParseResult<String> {
let start = reader.state.clone();
let start = reader.state;
let name = reader.read_while(|c| c.is_alphanumeric() || *c == '_' || *c == '-');
if name.is_empty() {
return Err(Error {

View File

@ -46,7 +46,7 @@ fn entry(reader: &mut Reader) -> ParseResult<Entry> {
}
fn request(reader: &mut Reader) -> ParseResult<Request> {
let start = reader.state.clone();
let start = reader.state;
let line_terminators = optional_line_terminators(reader)?;
let space0 = zero_or_more_spaces(reader)?;
let m = method(reader)?;
@ -93,7 +93,7 @@ fn request(reader: &mut Reader) -> ParseResult<Request> {
}
fn response(reader: &mut Reader) -> ParseResult<Response> {
let start = reader.state.clone();
let start = reader.state;
let line_terminators = optional_line_terminators(reader)?;
let space0 = zero_or_more_spaces(reader)?;
let _version = version(reader)?;
@ -132,7 +132,7 @@ fn method(reader: &mut Reader) -> ParseResult<Method> {
},
});
}
let start = reader.state.clone();
let start = reader.state;
let name = reader.read_while(|c| c.is_ascii_alphabetic());
if name.is_empty() || name.to_uppercase() != name {
Err(Error {
@ -146,7 +146,7 @@ fn method(reader: &mut Reader) -> ParseResult<Method> {
}
fn version(reader: &mut Reader) -> ParseResult<Version> {
let start = reader.state.clone();
let start = reader.state;
try_literal("HTTP", reader)?;
let next_c = reader.peek();

View File

@ -35,7 +35,7 @@ pub fn predicate(reader: &mut Reader) -> ParseResult<Predicate> {
// can not fail
fn predicate_not(reader: &mut Reader) -> (bool, Whitespace) {
let save = reader.state.clone();
let save = reader.state;
let no_whitespace = Whitespace {
value: String::new(),
source_info: SourceInfo {
@ -57,9 +57,9 @@ fn predicate_not(reader: &mut Reader) -> (bool, Whitespace) {
}
fn predicate_func(reader: &mut Reader) -> ParseResult<PredicateFunc> {
let start = reader.state.clone().pos;
let start = reader.state.pos;
let value = predicate_func_value(reader)?;
let end = reader.state.clone().pos;
let end = reader.state.pos;
Ok(PredicateFunc {
source_info: SourceInfo { start, end },
value,
@ -67,7 +67,7 @@ fn predicate_func(reader: &mut Reader) -> ParseResult<PredicateFunc> {
}
fn predicate_func_value(reader: &mut Reader) -> ParseResult<PredicateFuncValue> {
let start = reader.state.clone();
let start = reader.state;
match choice(
&[
equal_predicate,
@ -166,7 +166,7 @@ fn greater_predicate(reader: &mut Reader) -> ParseResult<PredicateFuncValue> {
} else {
one_or_more_spaces(reader)?
};
let start = reader.state.clone();
let start = reader.state;
let value = predicate_value(reader)?;
if value.is_number() || value.is_string() || value.is_expression() {
Ok(PredicateFuncValue::GreaterThan {
@ -193,7 +193,7 @@ fn greater_or_equal_predicate(reader: &mut Reader) -> ParseResult<PredicateFuncV
} else {
one_or_more_spaces(reader)?
};
let start = reader.state.clone();
let start = reader.state;
let value = predicate_value(reader)?;
if value.is_number() || value.is_string() || value.is_expression() {
Ok(PredicateFuncValue::GreaterThanOrEqual {
@ -220,7 +220,7 @@ fn less_predicate(reader: &mut Reader) -> ParseResult<PredicateFuncValue> {
} else {
one_or_more_spaces(reader)?
};
let start = reader.state.clone();
let start = reader.state;
let value = predicate_value(reader)?;
if value.is_number() || value.is_string() || value.is_expression() {
Ok(PredicateFuncValue::LessThan {
@ -247,7 +247,7 @@ fn less_or_equal_predicate(reader: &mut Reader) -> ParseResult<PredicateFuncValu
} else {
one_or_more_spaces(reader)?
};
let start = reader.state.clone();
let start = reader.state;
let value = predicate_value(reader)?;
if value.is_number() || value.is_string() || value.is_expression() {
Ok(PredicateFuncValue::LessThanOrEqual {
@ -267,7 +267,7 @@ fn less_or_equal_predicate(reader: &mut Reader) -> ParseResult<PredicateFuncValu
fn start_with_predicate(reader: &mut Reader) -> ParseResult<PredicateFuncValue> {
try_literal("startsWith", reader)?;
let space0 = one_or_more_spaces(reader)?;
let save = reader.state.clone();
let save = reader.state;
let value = predicate_value(reader)?;
if !value.is_string() && !value.is_bytearray() {
return Err(Error {
@ -282,7 +282,7 @@ fn start_with_predicate(reader: &mut Reader) -> ParseResult<PredicateFuncValue>
fn end_with_predicate(reader: &mut Reader) -> ParseResult<PredicateFuncValue> {
try_literal("endsWith", reader)?;
let space0 = one_or_more_spaces(reader)?;
let save = reader.state.clone();
let save = reader.state;
let value = predicate_value(reader)?;
if !value.is_string() && !value.is_bytearray() {
return Err(Error {
@ -297,7 +297,7 @@ fn end_with_predicate(reader: &mut Reader) -> ParseResult<PredicateFuncValue> {
fn contain_predicate(reader: &mut Reader) -> ParseResult<PredicateFuncValue> {
try_literal("contains", reader)?;
let space0 = one_or_more_spaces(reader)?;
let save = reader.state.clone();
let save = reader.state;
let value = predicate_value(reader)?;
if !value.is_string() && !value.is_bytearray() {
return Err(Error {
@ -319,7 +319,7 @@ fn include_predicate(reader: &mut Reader) -> ParseResult<PredicateFuncValue> {
fn match_predicate(reader: &mut Reader) -> ParseResult<PredicateFuncValue> {
try_literal("matches", reader)?;
let space0 = one_or_more_spaces(reader)?;
let save = reader.state.clone();
let save = reader.state;
let value = predicate_value(reader)?;
if !matches!(value, PredicateValue::String(_)) && !matches!(value, PredicateValue::Regex(_)) {
return Err(Error {

View File

@ -23,7 +23,7 @@ use crate::parser::string::*;
use crate::parser::{base64, filename, key_string, ParseResult};
pub fn space(reader: &mut Reader) -> ParseResult<Whitespace> {
let start = reader.state.clone();
let start = reader.state;
match reader.read() {
None => Err(Error {
pos: start.pos,
@ -53,7 +53,7 @@ pub fn space(reader: &mut Reader) -> ParseResult<Whitespace> {
}
pub fn one_or_more_spaces(reader: &mut Reader) -> ParseResult<Whitespace> {
let start = reader.state.clone();
let start = reader.state;
match one_or_more(space, reader) {
Ok(v) => {
let s = v.iter().map(|x| x.value.clone()).collect();
@ -72,7 +72,7 @@ pub fn one_or_more_spaces(reader: &mut Reader) -> ParseResult<Whitespace> {
}
pub fn zero_or_more_spaces(reader: &mut Reader) -> ParseResult<Whitespace> {
let start = reader.state.clone();
let start = reader.state;
match zero_or_more(space, reader) {
//Ok(v) => return Ok(v.join("")),
Ok(v) => {
@ -133,13 +133,13 @@ pub fn optional_line_terminators(reader: &mut Reader) -> ParseResult<Vec<LineTer
pub fn comment(reader: &mut Reader) -> ParseResult<Comment> {
try_literal("#", reader)?;
let start = reader.state.clone();
let start = reader.state;
let mut value = String::new();
loop {
if reader.is_eof() {
break;
}
let save_state = reader.state.clone();
let save_state = reader.state;
match newline(reader) {
Ok(_) => {
reader.state = save_state;
@ -157,7 +157,7 @@ pub fn comment(reader: &mut Reader) -> ParseResult<Comment> {
value,
source_info: SourceInfo {
start: start.pos,
end: reader.state.clone().pos,
end: reader.state.pos,
},
})
}
@ -167,9 +167,9 @@ pub fn literal(s: &str, reader: &mut Reader) -> ParseResult<()> {
// non recoverable parser
// => use combinator recover to make it recoverable
let start = reader.state.clone();
let start = reader.state;
for c in s.chars() {
let _state = reader.state.clone();
let _state = reader.state;
match reader.read() {
None => {
return Err(Error {
@ -201,7 +201,7 @@ pub fn literal(s: &str, reader: &mut Reader) -> ParseResult<()> {
pub fn try_literal(s: &str, reader: &mut Reader) -> ParseResult<()> {
// recoverable version which reset the cursor
// meant to be combined with following action
let save_state = reader.state.clone();
let save_state = reader.state;
match literal(s, reader) {
Ok(_) => Ok(()),
Err(e) => {
@ -217,15 +217,15 @@ pub fn try_literal(s: &str, reader: &mut Reader) -> ParseResult<()> {
// return the literal string
pub fn try_literals(s1: &str, s2: &str, reader: &mut Reader) -> ParseResult<String> {
let start = reader.state.clone();
let start = reader.state;
match literal(s1, reader) {
Ok(_) => Ok(s1.to_string()),
Err(_) => {
reader.state = start.clone();
reader.state = start;
match literal(s2, reader) {
Ok(_) => Ok(s2.to_string()),
Err(_) => {
reader.state = start.clone();
reader.state = start;
Err(Error {
pos: start.pos,
recoverable: true,
@ -240,7 +240,7 @@ pub fn try_literals(s1: &str, s2: &str, reader: &mut Reader) -> ParseResult<Stri
}
pub fn newline(reader: &mut Reader) -> ParseResult<Whitespace> {
let start = reader.state.clone();
let start = reader.state;
match try_literal("\r\n", reader) {
Ok(_) => Ok(Whitespace {
value: "\r\n".to_string(),
@ -300,7 +300,7 @@ pub fn hex(reader: &mut Reader) -> ParseResult<Hex> {
let start = reader.state.cursor;
let mut current: i32 = -1;
loop {
let s = reader.state.clone();
let s = reader.state;
match hex_digit(reader) {
Ok(d) => {
if current != -1 {
@ -405,7 +405,7 @@ pub fn null(reader: &mut Reader) -> ParseResult<()> {
}
pub fn boolean(reader: &mut Reader) -> ParseResult<bool> {
let start = reader.state.clone();
let start = reader.state;
match try_literal("true", reader) {
Ok(_) => Ok(true),
Err(_) => match literal("false", reader) {
@ -422,7 +422,7 @@ pub fn boolean(reader: &mut Reader) -> ParseResult<bool> {
}
pub fn natural(reader: &mut Reader) -> ParseResult<u64> {
let start = reader.state.clone();
let start = reader.state;
if reader.is_eof() {
return Err(Error {
@ -444,7 +444,7 @@ pub fn natural(reader: &mut Reader) -> ParseResult<u64> {
});
}
let save = reader.state.clone();
let save = reader.state;
let s = reader.read_while(|c| c.is_ascii_digit());
// if the first digit is zero, you should not have any more digits
@ -533,7 +533,7 @@ pub fn float(reader: &mut Reader) -> ParseResult<Float> {
}
pub(crate) fn file(reader: &mut Reader) -> ParseResult<File> {
let _start = reader.state.clone();
let _start = reader.state;
try_literal("file", reader)?;
literal(",", reader)?;
let space0 = zero_or_more_spaces(reader)?;
@ -550,11 +550,11 @@ pub(crate) fn file(reader: &mut Reader) -> ParseResult<File> {
pub(crate) fn base64(reader: &mut Reader) -> ParseResult<Base64> {
// base64 => can have whitespace
// support parser position
let _start = reader.state.clone();
let _start = reader.state;
try_literal("base64", reader)?;
literal(",", reader)?;
let space0 = zero_or_more_spaces(reader)?;
let save_state = reader.state.clone();
let save_state = reader.state;
let value = base64::parse(reader);
let count = reader.state.cursor - save_state.cursor;
reader.state = save_state;
@ -574,7 +574,7 @@ pub fn eof(reader: &mut Reader) -> ParseResult<()> {
Ok(())
} else {
Err(Error {
pos: reader.state.clone().pos,
pos: reader.state.pos,
recoverable: false,
inner: ParseError::Expecting {
value: String::from("eof"),

View File

@ -43,7 +43,7 @@ pub struct Reader {
pub state: ReaderState,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct ReaderState {
pub cursor: usize,
pub pos: Pos,

View File

@ -39,11 +39,11 @@ pub fn response_sections(reader: &mut Reader) -> ParseResult<Vec<Section>> {
fn request_section(reader: &mut Reader) -> ParseResult<Section> {
let line_terminators = optional_line_terminators(reader)?;
let space0 = zero_or_more_spaces(reader)?;
let start = reader.state.clone();
let start = reader.state.pos;
let name = section_name(reader)?;
let source_info = SourceInfo {
start: start.clone().pos,
end: reader.state.clone().pos,
start,
end: reader.state.pos,
};
let line_terminator0 = line_terminator(reader)?;
let value = match name.as_str() {
@ -56,8 +56,8 @@ fn request_section(reader: &mut Reader) -> ParseResult<Section> {
_ => {
return Err(Error {
pos: Pos {
line: start.pos.line,
column: start.pos.column + 1,
line: start.line,
column: start.column + 1,
},
recoverable: false,
inner: ParseError::RequestSectionName { name: name.clone() },
@ -77,11 +77,11 @@ fn request_section(reader: &mut Reader) -> ParseResult<Section> {
fn response_section(reader: &mut Reader) -> ParseResult<Section> {
let line_terminators = optional_line_terminators(reader)?;
let space0 = zero_or_more_spaces(reader)?;
let start = reader.state.clone();
let start = reader.state.pos;
let name = section_name(reader)?;
let source_info = SourceInfo {
start: start.clone().pos,
end: reader.state.clone().pos,
start,
end: reader.state.pos,
};
let line_terminator0 = line_terminator(reader)?;
let value = match name.as_str() {
@ -90,8 +90,8 @@ fn response_section(reader: &mut Reader) -> ParseResult<Section> {
_ => {
return Err(Error {
pos: Pos {
line: start.pos.line,
column: start.pos.column + 1,
line: start.line,
column: start.column + 1,
},
recoverable: false,
inner: ParseError::ResponseSectionName { name: name.clone() },
@ -188,7 +188,7 @@ fn cookie(reader: &mut Reader) -> ParseResult<Cookie> {
}
fn multipart_param(reader: &mut Reader) -> ParseResult<MultipartParam> {
let save = reader.state.clone();
let save = reader.state;
match file_param(reader) {
Ok(f) => Ok(MultipartParam::FileParam(f)),
Err(e) => {
@ -229,10 +229,10 @@ fn file_value(reader: &mut Reader) -> ParseResult<FileValue> {
let f = filename::parse(reader)?;
let space1 = zero_or_more_spaces(reader)?;
literal(";", reader)?;
let save = reader.state.clone();
let save = reader.state;
let (space2, content_type) = match line_terminator(reader) {
Ok(_) => {
reader.state = save.clone();
reader.state = save;
let space2 = Whitespace {
value: String::new(),
source_info: SourceInfo {
@ -260,16 +260,16 @@ fn file_value(reader: &mut Reader) -> ParseResult<FileValue> {
}
fn file_content_type(reader: &mut Reader) -> ParseResult<String> {
let start = reader.state.clone();
let start = reader.state;
let mut buf = String::new();
let mut spaces = String::new();
let mut save = reader.state.clone();
let mut save = reader.state;
while let Some(c) = reader.read() {
if c.is_alphanumeric() || c == '/' || c == ';' || c == '=' || c == '-' {
buf.push_str(spaces.as_str());
spaces = String::new();
buf.push(c);
save = reader.state.clone();
save = reader.state;
} else if c == ' ' {
spaces.push(' ');
} else {

View File

@ -27,10 +27,10 @@ use crate::parser::{template, ParseResult};
/// the string does not contain trailing space
/// 2- templatize
pub fn unquoted_template(reader: &mut Reader) -> ParseResult<Template> {
let start = reader.state.clone();
let start = reader.state;
let mut chars = vec![];
let mut spaces = vec![];
let mut end = start.clone();
let mut end = start;
loop {
let pos = reader.state.pos;
match any_char(vec!['#'], reader) {
@ -53,12 +53,12 @@ pub fn unquoted_template(reader: &mut Reader) -> ParseResult<Template> {
spaces = vec![];
}
chars.push((c, s, pos));
end = reader.state.clone();
end = reader.state;
}
}
}
}
reader.state = end.clone();
reader.state = end;
let encoded_string = template::EncodedString {
source_info: SourceInfo {
start: start.pos,
@ -87,13 +87,13 @@ pub fn quoted_oneline_string(reader: &mut Reader) -> ParseResult<String> {
}
pub fn quoted_template(reader: &mut Reader) -> ParseResult<Template> {
let start = reader.state.clone().pos;
let start = reader.state.pos;
let mut end = start;
try_literal("\"", reader)?;
let mut chars = vec![];
loop {
let pos = reader.state.pos;
let save = reader.state.clone();
let save = reader.state;
match any_char(vec!['"'], reader) {
Err(e) => {
if e.recoverable {
@ -105,7 +105,7 @@ pub fn quoted_template(reader: &mut Reader) -> ParseResult<Template> {
}
Ok((c, s)) => {
chars.push((c, s, pos));
end = reader.state.clone().pos;
end = reader.state.pos;
}
}
}
@ -127,13 +127,13 @@ pub fn quoted_template(reader: &mut Reader) -> ParseResult<Template> {
pub fn backtick_template(reader: &mut Reader) -> ParseResult<Template> {
let delimiter = Some('`');
let start = reader.state.clone().pos;
let start = reader.state.pos;
let mut end = start;
try_literal("`", reader)?;
let mut chars = vec![];
loop {
let pos = reader.state.pos;
let save = reader.state.clone();
let save = reader.state;
match any_char(vec!['`', '\n'], reader) {
Err(e) => {
if e.recoverable {
@ -145,7 +145,7 @@ pub fn backtick_template(reader: &mut Reader) -> ParseResult<Template> {
}
Ok((c, s)) => {
chars.push((c, s, pos));
end = reader.state.clone().pos;
end = reader.state.pos;
}
}
}
@ -166,12 +166,12 @@ pub fn backtick_template(reader: &mut Reader) -> ParseResult<Template> {
}
fn any_char(except: Vec<char>, reader: &mut Reader) -> ParseResult<(char, String)> {
let start = reader.state.clone();
let start = reader.state;
match escape_char(reader) {
Ok(c) => Ok((c, reader.peek_back(start.cursor))),
Err(e) => {
if e.recoverable {
reader.state = start.clone();
reader.state = start;
match reader.read() {
None => Err(Error {
pos: start.pos,
@ -205,7 +205,7 @@ fn any_char(except: Vec<char>, reader: &mut Reader) -> ParseResult<(char, String
fn escape_char(reader: &mut Reader) -> ParseResult<char> {
try_literal("\\", reader)?;
let start = reader.state.clone();
let start = reader.state;
match reader.read() {
Some('#') => Ok('#'),
Some('"') => Ok('"'),

View File

@ -24,8 +24,7 @@ use crate::parser::{expr, ParseResult};
pub fn url(reader: &mut Reader) -> ParseResult<Template> {
// Must be neither JSON-encoded nor empty.
// But more restrictive: whitelist characters, not empty
let start = reader.state.clone();
let start = reader.state;
let mut elements = vec![];
let mut buffer = String::new();
@ -46,13 +45,13 @@ pub fn url(reader: &mut Reader) -> ParseResult<Template> {
}
loop {
let save = reader.state.clone();
let save = reader.state;
match line_terminator(reader) {
Ok(_) => {
reader.state = save;
break;
}
_ => reader.state = save.clone(),
_ => reader.state = save,
}
match expr::parse(reader) {
@ -70,7 +69,7 @@ pub fn url(reader: &mut Reader) -> ParseResult<Template> {
if !e.recoverable {
return Err(e);
} else {
reader.state = save.clone();
reader.state = save;
match reader.read() {
None => break,
Some(c) => {
@ -100,7 +99,7 @@ pub fn url(reader: &mut Reader) -> ParseResult<Template> {
}
if elements.is_empty() {
reader.state = start.clone();
reader.state = start;
return Err(Error {
pos: start.pos,
recoverable: false,
@ -109,7 +108,7 @@ pub fn url(reader: &mut Reader) -> ParseResult<Template> {
}
// URLs should be followed by a line terminator
let save = reader.state.clone();
let save = reader.state;
if line_terminator(reader).is_err() {
reader.state = save;
let c = reader.peek().unwrap();
@ -126,7 +125,7 @@ pub fn url(reader: &mut Reader) -> ParseResult<Template> {
elements,
source_info: SourceInfo {
start: start.pos,
end: reader.state.clone().pos,
end: reader.state.pos,
},
})
}

View File

@ -47,7 +47,7 @@ use crate::parser::ParseResult;
/// byte a possible valid XML body.
///
pub fn parse(reader: &mut Reader) -> ParseResult<String> {
let start = reader.state.clone();
let start = reader.state;
// We test if our first character is a start of an XML text.
// If not, we return immediately a recoverable error.