Reuse reader from core ni JSONPath parser.

This commit is contained in:
Jean-Christophe Amiel 2024-06-28 14:22:37 +02:00
parent d026280b97
commit 8c77f625f3
No known key found for this signature in database
GPG Key ID: 07FF11CFD55356CC
6 changed files with 8 additions and 127 deletions

View File

@ -16,8 +16,8 @@
*
*/
use super::error::*;
use super::reader::Reader;
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;

View File

@ -15,7 +15,7 @@
* limitations under the License.
*
*/
use super::Pos;
use hurl_core::ast::Pos;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ParseError {

View File

@ -17,13 +17,7 @@
*/
use error::ParseError;
use reader::Reader;
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Pos {
pub line: usize,
pub column: usize,
}
use hurl_core::reader::Reader;
pub type ParseResult<T> = Result<T, ParseError>;
pub type ParseFunc<T> = fn(&mut Reader) -> ParseResult<T>;
@ -34,4 +28,3 @@ mod combinators;
mod error;
mod parse;
mod primitives;
mod reader;

View File

@ -19,8 +19,8 @@ use super::super::ast::*;
use super::combinators::*;
use super::error::{ParseError, ParseErrorKind};
use super::primitives::*;
use super::reader::Reader;
use super::ParseResult;
use hurl_core::reader::Reader;
pub fn parse(s: &str) -> Result<Query, ParseError> {
let mut reader = Reader::new(s);
@ -277,9 +277,8 @@ fn equal_string_predicate_func(reader: &mut Reader) -> ParseResult<PredicateFunc
#[cfg(test)]
mod tests {
use hurl_core::ast::Pos;
// tests from https://cburgmer.github.io/json-path-comparison
use super::super::Pos;
use super::*;
#[test]

View File

@ -17,7 +17,8 @@
*/
use super::super::ast::*;
use super::error::{ParseError, ParseErrorKind};
use super::{ParseResult, Reader};
use super::ParseResult;
use hurl_core::reader::Reader;
pub fn natural(reader: &mut Reader) -> ParseResult<usize> {
let start = reader.state;
@ -204,8 +205,8 @@ pub fn whitespace(reader: &mut Reader) {
#[cfg(test)]
mod tests {
use super::super::Pos;
use super::*;
use hurl_core::ast::Pos;
#[test]
fn test_natural() {

View File

@ -1,112 +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::Pos;
/// Represents a JSONPath reader.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Reader {
pub buffer: Vec<char>,
pub state: ReaderState,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct ReaderState {
pub cursor: usize,
pub pos: Pos,
}
impl Reader {
/// Creates a new reader.
pub fn new(s: &str) -> Reader {
Reader {
buffer: s.chars().collect(),
state: ReaderState {
cursor: 0,
pos: Pos { line: 1, column: 1 },
},
}
}
/// Returns true if the reader has read all the buffer, false otherwise.
pub fn is_eof(&self) -> bool {
self.state.cursor == self.buffer.len()
}
/// Returns the next char from the buffer advancing the internal state.
pub fn read(&mut self) -> Option<char> {
match self.buffer.get(self.state.cursor) {
None => None,
Some(c) => {
self.state.cursor += 1;
if !is_combining_character(*c) {
self.state.pos.column += 1;
}
if *c == '\n' {
self.state.pos.column = 1;
self.state.pos.line += 1;
}
Some(*c)
}
}
}
/// Returns chars from the buffer while `predicate` is true, advancing the internal state.
pub fn read_while(&mut self, predicate: fn(&char) -> bool) -> String {
let mut s = String::new();
loop {
match self.peek() {
None => return s,
Some(c) => {
if predicate(&c) {
s.push(self.read().unwrap());
} else {
return s;
}
}
}
}
}
/// Returns the next char from the buffer without advancing the internal state.
pub fn peek(&mut self) -> Option<char> {
self.buffer.get(self.state.cursor).copied()
}
}
fn is_combining_character(c: char) -> bool {
c > '\u{0300}' && c < '\u{036F}' // Combining Diacritical Marks (0300036F)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_reader() {
let mut reader = Reader::new("hi");
assert_eq!(reader.state.cursor, 0);
assert!(!reader.is_eof());
assert_eq!(reader.read().unwrap(), 'h');
assert_eq!(reader.state.cursor, 1);
assert_eq!(reader.peek().unwrap(), 'i');
assert_eq!(reader.state.cursor, 1);
assert_eq!(reader.read().unwrap(), 'i');
assert!(reader.is_eof());
assert_eq!(reader.read(), None);
}
}