mirror of
https://github.com/Orange-OpenSource/hurl.git
synced 2024-09-21 10:49:45 +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
|
// 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);
|
||||||
}
|
}
|
||||||
|
@ -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('=');
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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 {
|
||||||
|
@ -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(':'),
|
||||||
|
@ -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,
|
||||||
|
@ -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 {
|
||||||
|
@ -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();
|
||||||
|
@ -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 {
|
||||||
|
@ -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"),
|
||||||
|
@ -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,
|
||||||
|
@ -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 {
|
||||||
|
@ -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('"'),
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user