Change choice parser function signature to take a slice as argument.

With a slice as argument, we can use a vec or an array. In Hurl code, we use choice with array only.
We also change the implementation to remove the recursive call (and unncessary clone)
This commit is contained in:
jcamiel 2022-11-15 13:46:32 +01:00
parent b4c4d0ff77
commit a34480120e
No known key found for this signature in database
GPG Key ID: 07FF11CFD55356CC
10 changed files with 43 additions and 49 deletions

View File

@ -46,26 +46,23 @@ pub fn zero_or_more<'a, T>(f: ParseFunc<'a, T>, p: &mut Reader) -> ParseResult<'
}
}
// return the last error when no default error is specified
// typically this should be recoverable
pub fn choice<'a, T>(fs: Vec<ParseFunc<'a, T>>, p: &mut Reader) -> ParseResult<'a, T> {
match fs.get(0) {
None => panic!("You can call choice with an empty vector of choice"),
Some(f) => {
let start = p.state.clone();
if fs.len() == 1 {
f(p)
} else {
match f(p) {
Err(Error {
recoverable: true, ..
}) => {
p.state = start;
choice(fs.clone().into_iter().skip(1).collect(), p)
}
x => x,
}
/// Tries to apply the list of parser functions `fs` until one ot them succeeds.
/// Typically this should be recoverable
pub fn choice<'a, T>(fs: &[ParseFunc<'a, T>], reader: &mut Reader) -> ParseResult<'a, T> {
for (pos, f) in fs.iter().enumerate() {
let start = reader.state.clone();
if pos == fs.len() - 1 {
return f(reader);
}
match f(reader) {
Err(Error {
recoverable: true, ..
}) => {
reader.state = start;
continue;
}
x => return x,
}
}
panic!("You can't call choice with an empty vector of choice")
}

View File

@ -45,7 +45,7 @@ fn query(reader: &mut Reader) -> ParseResult<Query> {
fn selector(reader: &mut Reader) -> ParseResult<Selector> {
choice(
vec![
&[
selector_filter,
selector_wildcard,
selector_recursive_wildcard,
@ -241,7 +241,7 @@ fn predicate(reader: &mut Reader) -> ParseResult<Predicate> {
fn predicate_func(reader: &mut Reader) -> ParseResult<PredicateFunc> {
choice(
vec![
&[
equal_number_predicate_func,
greater_than_predicate_func,
greater_than_or_equal_predicate_func,

View File

@ -27,7 +27,7 @@ use super::ParseResult;
pub fn bytes(reader: &mut Reader) -> ParseResult<'static, Bytes> {
//let start = p.state.clone();
choice(
vec![
&[
raw_string_bytes,
json_bytes,
xml_bytes,

View File

@ -120,26 +120,23 @@ pub fn one_or_more<'a, T>(f: ParseFunc<'a, T>, reader: &mut Reader) -> ParseResu
}
}
pub fn choice<'a, T>(fs: Vec<ParseFunc<'a, T>>, reader: &mut Reader) -> ParseResult<'a, T> {
// return the last error when no default error is specified
// typically this should be recoverable
match fs.get(0) {
None => panic!("You can call choice with an empty vector of choice"),
Some(f) => {
let start = reader.state.clone();
if fs.len() == 1 {
f(reader)
} else {
match f(reader) {
Err(Error {
recoverable: true, ..
}) => {
reader.state = start;
choice(fs.clone().into_iter().skip(1).collect(), reader)
}
x => x,
}
/// Tries to apply the list of parser functions `fs` until one ot them succeeds.
/// Typically this should be recoverable
pub fn choice<'a, T>(fs: &[ParseFunc<'a, T>], reader: &mut Reader) -> ParseResult<'a, T> {
for (pos, f) in fs.iter().enumerate() {
let start = reader.state.clone();
if pos == fs.len() - 1 {
return f(reader);
}
match f(reader) {
Err(Error {
recoverable: true, ..
}) => {
reader.state = start;
continue;
}
x => return x,
}
}
panic!("You can't call choice with an empty vector of choice")
}

View File

@ -49,7 +49,7 @@ pub fn filters(reader: &mut Reader) -> ParseResult<'static, Vec<(Whitespace, Fil
pub fn filter(reader: &mut Reader) -> ParseResult<'static, Filter> {
let start = reader.state.pos.clone();
let value = choice(
vec![
&[
count_filter,
regex_filter,
url_encode_filter,

View File

@ -27,7 +27,7 @@ use crate::parser::expr;
pub fn parse(reader: &mut Reader) -> ParseResult<'static, JsonValue> {
choice(
vec![
&[
null_value,
boolean_value,
string_value,

View File

@ -71,7 +71,7 @@ fn predicate_func(reader: &mut Reader) -> ParseResult<'static, PredicateFunc> {
fn predicate_func_value(reader: &mut Reader) -> ParseResult<'static, PredicateFuncValue> {
let start = reader.state.clone();
match choice(
vec![
&[
equal_predicate,
not_equal_predicate,
greater_or_equal_predicate,

View File

@ -28,7 +28,7 @@ use crate::parser::{Error, ParseError};
pub fn predicate_value(reader: &mut Reader) -> ParseResult<'static, PredicateValue> {
choice(
vec![
&[
|p1| match null(p1) {
Ok(()) => Ok(PredicateValue::Null {}),
Err(e) => Err(e),

View File

@ -37,7 +37,7 @@ pub fn query(reader: &mut Reader) -> ParseResult<'static, Query> {
fn query_value(reader: &mut Reader) -> ParseResult<'static, QueryValue> {
choice(
vec![
&[
status_query,
url_query,
header_query,
@ -133,7 +133,7 @@ fn regex_query(reader: &mut Reader) -> ParseResult<'static, QueryValue> {
pub fn regex_value(reader: &mut Reader) -> ParseResult<'static, RegexValue> {
choice(
vec![
&[
|p1| match quoted_template(p1) {
Ok(value) => Ok(RegexValue::Template(value)),
Err(e) => Err(e),

View File

@ -347,7 +347,7 @@ fn assert(reader: &mut Reader) -> ParseResult<'static, Assert> {
fn option(reader: &mut Reader) -> ParseResult<'static, EntryOption> {
choice(
vec![
&[
option_cacert,
option_compressed,
option_insecure,
@ -595,7 +595,7 @@ fn variable_name(reader: &mut Reader) -> ParseResult<'static, String> {
fn variable_value(reader: &mut Reader) -> ParseResult<'static, VariableValue> {
choice(
vec![
&[
|p1| match null(p1) {
Ok(()) => Ok(VariableValue::Null {}),
Err(e) => Err(e),