mirror of
https://github.com/Orange-OpenSource/hurl.git
synced 2024-11-29 13:43:53 +03:00
Use combinator in jsonpath parser.
This commit is contained in:
parent
89f7313ce6
commit
e07470c326
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Hurl (https://hurl.dev)
|
||||
* Copyright (C) 2024 Orange
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
use super::error::*;
|
||||
use super::{ParseFunc, ParseResult};
|
||||
use hurl_core::reader::Reader;
|
||||
|
||||
pub fn zero_or_more<T>(f: ParseFunc<T>, p: &mut Reader) -> ParseResult<Vec<T>> {
|
||||
let _start = p.state;
|
||||
|
||||
let mut v: Vec<T> = Vec::new();
|
||||
loop {
|
||||
let initial_state = p.state;
|
||||
if p.is_eof() {
|
||||
return Ok(v);
|
||||
}
|
||||
|
||||
match f(p) {
|
||||
Ok(r) => {
|
||||
v.push(r);
|
||||
}
|
||||
Err(e) => {
|
||||
return if e.recoverable {
|
||||
p.state.pos = initial_state.pos;
|
||||
p.state.cursor = initial_state.cursor;
|
||||
Ok(v)
|
||||
} else {
|
||||
Err(e)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Tries to apply the list of parser functions `fs` until one of them succeeds.
|
||||
/// 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;
|
||||
if pos == fs.len() - 1 {
|
||||
return f(reader);
|
||||
}
|
||||
match f(reader) {
|
||||
Err(ParseError {
|
||||
recoverable: true, ..
|
||||
}) => {
|
||||
reader.state = start;
|
||||
continue;
|
||||
}
|
||||
x => return x,
|
||||
}
|
||||
}
|
||||
panic!("You can't call choice with an empty vector of choice")
|
||||
}
|
@ -18,6 +18,8 @@
|
||||
|
||||
use hurl_core::reader::Pos;
|
||||
|
||||
pub type ParseResult<T> = Result<T, ParseError>;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct ParseError {
|
||||
pub pos: Pos,
|
||||
@ -39,3 +41,23 @@ impl ParseError {
|
||||
pub enum ParseErrorKind {
|
||||
Expecting(String),
|
||||
}
|
||||
|
||||
impl hurl_core::combinator::ParseError for ParseError {
|
||||
fn is_recoverable(&self) -> bool {
|
||||
self.recoverable
|
||||
}
|
||||
|
||||
fn to_recoverable(self) -> Self {
|
||||
ParseError {
|
||||
recoverable: true,
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
||||
fn to_non_recoverable(self) -> Self {
|
||||
ParseError {
|
||||
recoverable: false,
|
||||
..self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,16 +15,8 @@
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
use error::ParseError;
|
||||
use hurl_core::reader::Reader;
|
||||
|
||||
pub type ParseResult<T> = Result<T, ParseError>;
|
||||
pub type ParseFunc<T> = fn(&mut Reader) -> ParseResult<T>;
|
||||
|
||||
pub use self::parse::parse;
|
||||
|
||||
mod combinators;
|
||||
mod error;
|
||||
mod parse;
|
||||
mod primitives;
|
||||
|
@ -15,11 +15,12 @@
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
use super::super::ast::*;
|
||||
use super::combinators::*;
|
||||
use super::error::{ParseError, ParseErrorKind};
|
||||
use super::primitives::*;
|
||||
use super::ParseResult;
|
||||
use crate::jsonpath::ast::{Predicate, PredicateFunc, Query, Selector, Slice};
|
||||
use crate::jsonpath::parser::error::{ParseError, ParseErrorKind, ParseResult};
|
||||
use crate::jsonpath::parser::primitives::{
|
||||
integer, key_name, key_path, literal, natural, number, string_value, try_literal, whitespace,
|
||||
};
|
||||
use hurl_core::combinator::{choice, zero_or_more};
|
||||
use hurl_core::reader::Reader;
|
||||
|
||||
pub fn parse(s: &str) -> Result<Query, ParseError> {
|
||||
@ -277,6 +278,7 @@ fn equal_string_predicate_func(reader: &mut Reader) -> ParseResult<PredicateFunc
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::jsonpath::ast::Number;
|
||||
use hurl_core::reader::Pos;
|
||||
// tests from https://cburgmer.github.io/json-path-comparison
|
||||
use super::*;
|
||||
|
@ -15,9 +15,8 @@
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
use super::super::ast::*;
|
||||
use super::error::{ParseError, ParseErrorKind};
|
||||
use super::ParseResult;
|
||||
use crate::jsonpath::ast::Number;
|
||||
use crate::jsonpath::parser::error::{ParseError, ParseErrorKind, ParseResult};
|
||||
use hurl_core::reader::Reader;
|
||||
|
||||
pub fn natural(reader: &mut Reader) -> ParseResult<usize> {
|
||||
|
Loading…
Reference in New Issue
Block a user