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 // The String can only be null, a bool, a number
// It will be easier when your variables value have a type // It will be easier when your variables value have a type
let mut reader = Reader::new(s.as_str()); 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() { if parse_json_number(&mut reader).is_ok() {
return Ok(s); return Ok(s);
} }
reader.state = start.clone(); reader.state = start;
if parse_json_boolean(&mut reader).is_ok() { if parse_json_boolean(&mut reader).is_ok() {
return Ok(s); return Ok(s);
} }

View File

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

View File

@ -20,7 +20,7 @@ use crate::parser::reader::Reader;
use crate::parser::{ParseFunc, ParseResult}; use crate::parser::{ParseFunc, ParseResult};
pub fn optional<T>(f: ParseFunc<T>, reader: &mut Reader) -> ParseResult<Option<T>> { 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) { match f(reader) {
Ok(r) => Ok(Some(r)), Ok(r) => Ok(Some(r)),
Err(e) => { 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>> { 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(); let mut v: Vec<T> = Vec::new();
loop { loop {
let initial_state = reader.state.clone(); let initial_state = reader.state;
if reader.is_eof() { if reader.is_eof() {
return Ok(v); 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>> { 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) { match f(reader) {
Ok(first) => { Ok(first) => {
let mut v = vec![first]; let mut v = vec![first];
loop { loop {
let initial_state = reader.state.clone(); let initial_state = reader.state;
match f(reader) { match f(reader) {
Ok(r) => { Ok(r) => {
v.push(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 /// Typically this should be recoverable
pub fn choice<T>(fs: &[ParseFunc<T>], reader: &mut Reader) -> ParseResult<T> { pub fn choice<T>(fs: &[ParseFunc<T>], reader: &mut Reader) -> ParseResult<T> {
for (pos, f) in fs.iter().enumerate() { for (pos, f) in fs.iter().enumerate() {
let start = reader.state.clone(); let start = reader.state;
if pos == fs.len() - 1 { if pos == fs.len() - 1 {
return f(reader); 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> { 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 == '-'); let name = reader.read_while(|c| c.is_alphanumeric() || *c == '_' || *c == '-');
if name.is_empty() { if name.is_empty() {
return Err(Error { return Err(Error {

View File

@ -24,7 +24,7 @@ pub fn parse(reader: &mut Reader) -> ParseResult<Filename> {
// This is an absolute file // This is an absolute file
// that you have to write with a relative name // that you have to write with a relative name
// default root_dir is the hurl directory // default root_dir is the hurl directory
let start = reader.state.clone(); let start = reader.state;
let s = reader.read_while_escaping(|c| { let s = reader.read_while_escaping(|c| {
c.is_alphanumeric() || *c == '.' || *c == '/' || *c == '_' || *c == '-' c.is_alphanumeric() || *c == '.' || *c == '/' || *c == '_' || *c == '-'
}); });
@ -40,7 +40,7 @@ pub fn parse(reader: &mut Reader) -> ParseResult<Filename> {
value: s, value: s,
source_info: SourceInfo { source_info: SourceInfo {
start: start.pos, 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)>> { pub fn filters(reader: &mut Reader) -> ParseResult<Vec<(Whitespace, Filter)>> {
let mut filters = vec![]; let mut filters = vec![];
loop { loop {
let save = reader.state.clone(); let save = reader.state;
let space = zero_or_more_spaces(reader)?; let space = zero_or_more_spaces(reader)?;
if space.value.is_empty() { if space.value.is_empty() {
break; 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)> { fn any_char(reader: &mut Reader) -> ParseResult<(char, String, Pos)> {
let start = reader.state.clone(); let start = reader.state;
match escape_char(reader) { match escape_char(reader) {
Ok(c) => Ok((c, reader.peek_back(start.cursor), start.pos)), Ok(c) => Ok((c, reader.peek_back(start.cursor), start.pos)),
Err(e) => { Err(e) => {
if e.recoverable { if e.recoverable {
reader.state = start.clone(); reader.state = start;
match reader.read() { match reader.read() {
None => Err(error::Error { None => Err(error::Error {
pos: start.pos, 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> { fn escape_char(reader: &mut Reader) -> ParseResult<char> {
try_literal("\\", reader)?; try_literal("\\", reader)?;
let start = reader.state.clone(); let start = reader.state;
match reader.read() { match reader.read() {
Some('"') => Ok('"'), Some('"') => Ok('"'),
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> { pub fn number_value(reader: &mut Reader) -> ParseResult<JsonValue> {
let start = reader.state.clone(); let start = reader.state;
let sign = match try_literal("-", reader) { let sign = match try_literal("-", reader) {
Err(_) => String::new(), Err(_) => String::new(),
@ -360,7 +360,7 @@ pub fn object_value(reader: &mut Reader) -> ParseResult<JsonValue> {
} }
fn key(reader: &mut Reader) -> ParseResult<Template> { 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())?; let name = string_template(reader).map_err(|e| e.non_recoverable())?;
if name.elements.is_empty() { if name.elements.is_empty() {
Err(error::Error { Err(error::Error {

View File

@ -23,7 +23,7 @@ use crate::parser::template::template;
use crate::parser::{string, ParseResult}; use crate::parser::{string, ParseResult};
pub fn parse(reader: &mut Reader) -> ParseResult<Template> { pub fn parse(reader: &mut Reader) -> ParseResult<Template> {
let start = reader.state.clone(); let start = reader.state;
let mut elements = vec![]; let mut elements = vec![];
loop { loop {
@ -70,7 +70,7 @@ pub fn parse(reader: &mut Reader) -> ParseResult<Template> {
} }
} }
let end = reader.state.clone(); let end = reader.state;
Ok(Template { Ok(Template {
delimiter: None, delimiter: None,
elements, elements,
@ -108,7 +108,7 @@ fn key_string_content(reader: &mut Reader) -> ParseResult<String> {
fn key_string_text(reader: &mut Reader) -> String { fn key_string_text(reader: &mut Reader) -> String {
let mut s = String::new(); let mut s = String::new();
loop { loop {
let save = reader.state.clone(); let save = reader.state;
match reader.read() { match reader.read() {
None => break, None => break,
Some(c) => { Some(c) => {
@ -135,7 +135,7 @@ fn key_string_text(reader: &mut Reader) -> String {
fn key_string_escaped_char(reader: &mut Reader) -> ParseResult<char> { fn key_string_escaped_char(reader: &mut Reader) -> ParseResult<char> {
try_literal("\\", reader)?; try_literal("\\", reader)?;
let start = reader.state.clone(); let start = reader.state;
match reader.read() { match reader.read() {
Some('#') => Ok('#'), Some('#') => Ok('#'),
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> { pub fn multiline_string(reader: &mut Reader) -> ParseResult<MultilineString> {
try_literal("```", reader)?; try_literal("```", reader)?;
let save = reader.state.clone(); let save = reader.state;
match choice(&[json_text, xml_text, graphql, plain_text], reader) { match choice(&[json_text, xml_text, graphql, plain_text], reader) {
Ok(multi) => Ok(multi), Ok(multi) => Ok(multi),
@ -141,7 +141,7 @@ fn graphql(reader: &mut Reader) -> ParseResult<MultilineString> {
} }
fn whitespace(reader: &mut Reader) -> ParseResult<Whitespace> { fn whitespace(reader: &mut Reader) -> ParseResult<Whitespace> {
let start = reader.state.clone(); let start = reader.state;
match reader.read() { match reader.read() {
None => Err(Error { None => Err(Error {
pos: start.pos, pos: start.pos,
@ -171,7 +171,7 @@ fn whitespace(reader: &mut Reader) -> ParseResult<Whitespace> {
} }
fn zero_or_more_whitespaces(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) { match zero_or_more(whitespace, reader) {
Ok(v) => { Ok(v) => {
let s = v.iter().map(|x| x.value.clone()).collect(); 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> { fn graphql_variables(reader: &mut Reader) -> ParseResult<GraphQlVariables> {
try_literal("variables", reader)?; try_literal("variables", reader)?;
let space = zero_or_more_spaces(reader)?; let space = zero_or_more_spaces(reader)?;
let start = reader.state.clone(); let start = reader.state;
let object = object_value(reader); let object = object_value(reader);
let value = match object { let value = match object {
Ok(obj) => obj, Ok(obj) => obj,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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