mirror of
https://github.com/Orange-OpenSource/hurl.git
synced 2024-11-11 02:40:26 +03:00
Implement Copy for ReaderState.
This commit is contained in:
parent
bf8deaf1cd
commit
4fbbb6d683
@ -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);
|
||||
}
|
||||
|
@ -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('=');
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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(':'),
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
@ -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 {
|
||||
|
@ -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"),
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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('"'),
|
||||
|
@ -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,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user