Make Reader fields private.

This commit is contained in:
Jean-Christophe Amiel 2024-07-01 15:52:13 +02:00
parent e7a6544494
commit 76b45a1ed1
No known key found for this signature in database
GPG Key ID: 07FF11CFD55356CC
26 changed files with 533 additions and 551 deletions

View File

@ -34,7 +34,7 @@ fn query(reader: &mut Reader) -> ParseResult<Query> {
let selectors = zero_or_more(selector, reader)?;
if !reader.is_eof() {
let kind = ParseErrorKind::Expecting("eof".to_string());
let error = ParseError::new(reader.cursor.pos, false, kind);
let error = ParseError::new(reader.cursor().pos, false, kind);
return Err(error);
}
Ok(Query { selectors })
@ -58,7 +58,7 @@ fn selector(reader: &mut Reader) -> ParseResult<Selector> {
}
fn selector_array_index_or_array_indices(reader: &mut Reader) -> Result<Selector, ParseError> {
let initial_state = reader.cursor;
let initial_state = reader.cursor();
try_left_bracket(reader)?;
let mut indexes = vec![];
let i = match natural(reader) {
@ -70,7 +70,7 @@ fn selector_array_index_or_array_indices(reader: &mut Reader) -> Result<Selector
};
indexes.push(i);
loop {
let state = reader.cursor;
let start = reader.cursor();
if try_literal(",", reader).is_ok() {
let i = match natural(reader) {
Err(e) => {
@ -80,15 +80,15 @@ fn selector_array_index_or_array_indices(reader: &mut Reader) -> Result<Selector
};
indexes.push(i);
} else {
reader.cursor = state;
reader.seek(start);
break;
}
}
// you will have a ':' for a slice
// TODO: combine array index, indices and slice in the same function
if let Err(e) = try_literal("]", reader) {
reader.cursor = initial_state;
return Err(ParseError::new(reader.cursor.pos, true, e.kind));
reader.seek(initial_state);
return Err(ParseError::new(reader.cursor().pos, true, e.kind));
}
let selector = if indexes.len() == 1 {
Selector::ArrayIndex(*indexes.first().unwrap())
@ -107,23 +107,23 @@ fn selector_array_wildcard(reader: &mut Reader) -> Result<Selector, ParseError>
fn selector_array_slice(reader: &mut Reader) -> Result<Selector, ParseError> {
try_left_bracket(reader)?;
let state = reader.cursor;
let save = reader.cursor();
let start = match integer(reader) {
Err(_) => {
reader.cursor = state;
reader.seek(save);
None
}
Ok(v) => Some(v),
};
if try_literal(":", reader).is_err() {
let kind = ParseErrorKind::Expecting(":".to_string());
let error = ParseError::new(state.pos, true, kind);
let error = ParseError::new(save.pos, true, kind);
return Err(error);
};
let state = reader.cursor;
let save = reader.cursor();
let end = match integer(reader) {
Err(_) => {
reader.cursor = state;
reader.seek(save);
None
}
Ok(v) => Some(v),
@ -145,7 +145,7 @@ fn selector_object_key_bracket(reader: &mut Reader) -> Result<Selector, ParseErr
match string_value(reader) {
Err(_) => {
let kind = ParseErrorKind::Expecting("value string".to_string());
let error = ParseError::new(reader.cursor.pos, true, kind);
let error = ParseError::new(reader.cursor().pos, true, kind);
Err(error)
}
Ok(v) => {
@ -158,7 +158,7 @@ fn selector_object_key_bracket(reader: &mut Reader) -> Result<Selector, ParseErr
fn selector_object_key(reader: &mut Reader) -> Result<Selector, ParseError> {
if reader.peek() != Some('.') {
let kind = ParseErrorKind::Expecting("[ or .".to_string());
let error = ParseError::new(reader.cursor.pos, true, kind);
let error = ParseError::new(reader.cursor().pos, true, kind);
return Err(error);
};
_ = reader.read();
@ -166,7 +166,7 @@ fn selector_object_key(reader: &mut Reader) -> Result<Selector, ParseError> {
let s = reader.read_while(|c| c.is_alphanumeric() || *c == '_' || *c == '-');
if s.is_empty() {
let kind = ParseErrorKind::Expecting("empty value".to_string());
let error = ParseError::new(reader.cursor.pos, false, kind);
let error = ParseError::new(reader.cursor().pos, false, kind);
return Err(error);
}
Ok(Selector::NameChild(s))
@ -189,9 +189,9 @@ fn selector_recursive_key(reader: &mut Reader) -> Result<Selector, ParseError> {
}
fn try_left_bracket(reader: &mut Reader) -> Result<(), ParseError> {
let start = reader.cursor;
let start = reader.cursor();
if literal(".[", reader).is_err() {
reader.cursor = start;
reader.seek(start);
try_literal("[", reader)?;
}
Ok(())
@ -209,11 +209,11 @@ fn predicate(reader: &mut Reader) -> ParseResult<Predicate> {
// @.key>=value GreaterThanOrEqual(Key, Value)
literal("@.", reader)?; // assume key value for the time being
let key = key_path(reader)?;
let state = reader.cursor;
let save = reader.cursor();
let func = match predicate_func(reader) {
Ok(f) => f,
Err(_) => {
reader.cursor = state;
reader.seek(save);
PredicateFunc::KeyExist
}
};
@ -291,11 +291,11 @@ mod tests {
let mut reader = Reader::new("[xxx");
assert!(try_left_bracket(&mut reader).is_ok());
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
let mut reader = Reader::new(".[xxx");
assert!(try_left_bracket(&mut reader).is_ok());
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
}
#[test]
@ -372,7 +372,7 @@ mod tests {
func: PredicateFunc::KeyExist,
})
);
assert_eq!(reader.cursor.offset, 11);
assert_eq!(reader.cursor().offset, 11);
// Filter equal on string with single quotes
let mut reader = Reader::new("[?(@.key=='value')]");
@ -383,7 +383,7 @@ mod tests {
func: PredicateFunc::EqualString("value".to_string()),
})
);
assert_eq!(reader.cursor.offset, 19);
assert_eq!(reader.cursor().offset, 19);
let mut reader = Reader::new(".[?(@.key=='value')]");
assert_eq!(
selector(&mut reader).unwrap(),
@ -392,7 +392,7 @@ mod tests {
func: PredicateFunc::EqualString("value".to_string()),
})
);
assert_eq!(reader.cursor.offset, 20);
assert_eq!(reader.cursor().offset, 20);
let mut reader = Reader::new("[?(@.price<10)]");
assert_eq!(
@ -405,7 +405,7 @@ mod tests {
}),
})
);
assert_eq!(reader.cursor.offset, 15);
assert_eq!(reader.cursor().offset, 15);
}
#[test]
@ -415,40 +415,40 @@ mod tests {
selector(&mut reader).unwrap(),
Selector::RecursiveKey("book".to_string())
);
assert_eq!(reader.cursor.offset, 6);
assert_eq!(reader.cursor().offset, 6);
}
#[test]
pub fn test_selector_array_index() {
let mut reader = Reader::new("[2]");
assert_eq!(selector(&mut reader).unwrap(), Selector::ArrayIndex(2));
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
let mut reader = Reader::new("[0,1]");
assert_eq!(
selector(&mut reader).unwrap(),
Selector::ArrayIndices(vec![0, 1])
);
assert_eq!(reader.cursor.offset, 5);
assert_eq!(reader.cursor().offset, 5);
// you don't need to keep the exact string
// this is not part of the AST
let mut reader = Reader::new(".[2]");
assert_eq!(selector(&mut reader).unwrap(), Selector::ArrayIndex(2));
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
}
#[test]
pub fn test_selector_wildcard() {
let mut reader = Reader::new("[*]");
assert_eq!(selector(&mut reader).unwrap(), Selector::ArrayWildcard);
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
// you don't need to keep the exact string
// this is not part of the AST
let mut reader = Reader::new(".[*]");
assert_eq!(selector(&mut reader).unwrap(), Selector::ArrayWildcard);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
}
#[test]
@ -461,7 +461,7 @@ mod tests {
end: None
})
);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
let mut reader = Reader::new("[-1:]");
assert_eq!(
@ -471,7 +471,7 @@ mod tests {
end: None
})
);
assert_eq!(reader.cursor.offset, 5);
assert_eq!(reader.cursor().offset, 5);
let mut reader = Reader::new("[:2]");
assert_eq!(
@ -481,7 +481,7 @@ mod tests {
end: Some(2)
})
);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
}
#[test]
@ -491,21 +491,21 @@ mod tests {
selector(&mut reader).unwrap(),
Selector::NameChild("key".to_string())
);
assert_eq!(reader.cursor.offset, 7);
assert_eq!(reader.cursor().offset, 7);
let mut reader = Reader::new(".['key']");
assert_eq!(
selector(&mut reader).unwrap(),
Selector::NameChild("key".to_string())
);
assert_eq!(reader.cursor.offset, 8);
assert_eq!(reader.cursor().offset, 8);
let mut reader = Reader::new("['key1']");
assert_eq!(
selector(&mut reader).unwrap(),
Selector::NameChild("key1".to_string())
);
assert_eq!(reader.cursor.offset, 8);
assert_eq!(reader.cursor().offset, 8);
}
#[test]
@ -515,14 +515,14 @@ mod tests {
selector(&mut reader).unwrap(),
Selector::NameChild("key".to_string())
);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
let mut reader = Reader::new(".key1");
assert_eq!(
selector(&mut reader).unwrap(),
Selector::NameChild("key1".to_string())
);
assert_eq!(reader.cursor.offset, 5);
assert_eq!(reader.cursor().offset, 5);
}
#[test]
@ -583,7 +583,7 @@ mod tests {
predicate_func(&mut reader).unwrap(),
PredicateFunc::Equal(Number { int: 2, decimal: 0 })
);
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
let mut reader = Reader::new("==2.1");
assert_eq!(
@ -593,7 +593,7 @@ mod tests {
decimal: 100_000_000_000_000_000
})
);
assert_eq!(reader.cursor.offset, 5);
assert_eq!(reader.cursor().offset, 5);
let mut reader = Reader::new("== 2.1 ");
assert_eq!(
@ -603,41 +603,41 @@ mod tests {
decimal: 100_000_000_000_000_000
})
);
assert_eq!(reader.cursor.offset, 7);
assert_eq!(reader.cursor().offset, 7);
let mut reader = Reader::new("=='hello'");
assert_eq!(
predicate_func(&mut reader).unwrap(),
PredicateFunc::EqualString("hello".to_string())
);
assert_eq!(reader.cursor.offset, 9);
assert_eq!(reader.cursor().offset, 9);
let mut reader = Reader::new(">5");
assert_eq!(
predicate_func(&mut reader).unwrap(),
PredicateFunc::GreaterThan(Number { int: 5, decimal: 0 })
);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new(">=5");
assert_eq!(
predicate_func(&mut reader).unwrap(),
PredicateFunc::GreaterThanOrEqual(Number { int: 5, decimal: 0 })
);
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
let mut reader = Reader::new("<5");
assert_eq!(
predicate_func(&mut reader).unwrap(),
PredicateFunc::LessThan(Number { int: 5, decimal: 0 })
);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("<=5");
assert_eq!(
predicate_func(&mut reader).unwrap(),
PredicateFunc::LessThanOrEqual(Number { int: 5, decimal: 0 })
);
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
}
}

View File

@ -20,7 +20,7 @@ use crate::jsonpath::parser::error::{ParseError, ParseErrorKind, ParseResult};
use hurl_core::reader::Reader;
pub fn natural(reader: &mut Reader) -> ParseResult<usize> {
let start = reader.cursor;
let start = reader.cursor();
if reader.is_eof() {
let kind = ParseErrorKind::Expecting("natural".to_string());
@ -34,7 +34,7 @@ pub fn natural(reader: &mut Reader) -> ParseResult<usize> {
return Err(error);
}
let save = reader.cursor;
let save = reader.cursor();
let s = reader.read_while(|c| c.is_ascii_digit());
// if the first digit is zero, you should not have any more digits
@ -64,14 +64,14 @@ pub fn number(reader: &mut Reader) -> ParseResult<Number> {
_ = reader.read();
if reader.is_eof() {
let kind = ParseErrorKind::Expecting("natural".to_string());
let error = ParseError::new(reader.cursor.pos, false, kind);
let error = ParseError::new(reader.cursor().pos, false, kind);
return Err(error);
}
let s = reader.read_while(|c| c.is_ascii_digit());
if s.is_empty() {
let kind = ParseErrorKind::Expecting("natural".to_string());
let error = ParseError::new(reader.cursor.pos, false, kind);
let error = ParseError::new(reader.cursor().pos, false, kind);
return Err(error);
}
format!("{s:0<18}").parse().unwrap()
@ -89,7 +89,7 @@ pub fn string_value(reader: &mut Reader) -> Result<String, ParseError> {
match reader.read() {
None => {
let kind = ParseErrorKind::Expecting("'".to_string());
let error = ParseError::new(reader.cursor.pos, false, kind);
let error = ParseError::new(reader.cursor().pos, false, kind);
return Err(error);
}
Some('\'') => break,
@ -101,7 +101,7 @@ pub fn string_value(reader: &mut Reader) -> Result<String, ParseError> {
}
_ => {
let kind = ParseErrorKind::Expecting("'".to_string());
let error = ParseError::new(reader.cursor.pos, false, kind);
let error = ParseError::new(reader.cursor().pos, false, kind);
return Err(error);
}
}
@ -126,13 +126,13 @@ pub fn key_name(reader: &mut Reader) -> Result<String, ParseError> {
c
} else {
let kind = ParseErrorKind::Expecting("key".to_string());
let error = ParseError::new(reader.cursor.pos, false, kind);
let error = ParseError::new(reader.cursor().pos, false, kind);
return Err(error);
}
}
None => {
let kind = ParseErrorKind::Expecting("key".to_string());
let error = ParseError::new(reader.cursor.pos, false, kind);
let error = ParseError::new(reader.cursor().pos, false, kind);
return Err(error);
}
};
@ -157,7 +157,7 @@ pub fn literal(s: &str, reader: &mut Reader) -> ParseResult<()> {
// does not return a value
// non recoverable reader
// => use combinator recover to make it recoverable
let start = reader.cursor;
let start = reader.cursor();
if reader.is_eof() {
let kind = ParseErrorKind::Expecting(s.to_string());
let error = ParseError::new(start.pos, false, kind);
@ -211,15 +211,15 @@ mod tests {
fn test_natural() {
let mut reader = Reader::new("0");
assert_eq!(natural(&mut reader).unwrap(), 0);
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
let mut reader = Reader::new("0.");
assert_eq!(natural(&mut reader).unwrap(), 0);
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
let mut reader = Reader::new("10x");
assert_eq!(natural(&mut reader).unwrap(), 10);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
}
#[test]
@ -265,11 +265,11 @@ mod tests {
fn test_number() {
let mut reader = Reader::new("1");
assert_eq!(number(&mut reader).unwrap(), Number { int: 1, decimal: 0 });
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
let mut reader = Reader::new("1.0");
assert_eq!(number(&mut reader).unwrap(), Number { int: 1, decimal: 0 });
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
let mut reader = Reader::new("-1.0");
assert_eq!(
@ -279,7 +279,7 @@ mod tests {
decimal: 0
}
);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
let mut reader = Reader::new("1.1");
assert_eq!(
@ -289,7 +289,7 @@ mod tests {
decimal: 100_000_000_000_000_000
}
);
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
let mut reader = Reader::new("1.100");
assert_eq!(
@ -299,7 +299,7 @@ mod tests {
decimal: 100_000_000_000_000_000
}
);
assert_eq!(reader.cursor.offset, 5);
assert_eq!(reader.cursor().offset, 5);
let mut reader = Reader::new("1.01");
assert_eq!(
@ -309,7 +309,7 @@ mod tests {
decimal: 10_000_000_000_000_000
}
);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
let mut reader = Reader::new("1.010");
assert_eq!(
@ -319,7 +319,7 @@ mod tests {
decimal: 10_000_000_000_000_000
}
);
assert_eq!(reader.cursor.offset, 5);
assert_eq!(reader.cursor().offset, 5);
let mut reader = Reader::new("-0.333333333333333333");
assert_eq!(
@ -329,7 +329,7 @@ mod tests {
decimal: 333_333_333_333_333_333
}
);
assert_eq!(reader.cursor.offset, 21);
assert_eq!(reader.cursor().offset, 21);
}
#[test]
@ -415,28 +415,28 @@ mod tests {
fn test_literal() {
let mut reader = Reader::new("hello");
assert_eq!(literal("hello", &mut reader), Ok(()));
assert_eq!(reader.cursor.offset, 5);
assert_eq!(reader.cursor().offset, 5);
let mut reader = Reader::new("hello ");
assert_eq!(literal("hello", &mut reader), Ok(()));
assert_eq!(reader.cursor.offset, 6);
assert_eq!(reader.cursor().offset, 6);
let mut reader = Reader::new("");
let error = literal("hello", &mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 1 });
assert_eq!(error.kind, ParseErrorKind::Expecting("hello".to_string()));
assert_eq!(reader.cursor.offset, 0);
assert_eq!(reader.cursor().offset, 0);
let mut reader = Reader::new("hi");
let error = literal("hello", &mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 1 });
assert_eq!(error.kind, ParseErrorKind::Expecting("hello".to_string()));
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("he");
let error = literal("hello", &mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 1 });
assert_eq!(error.kind, ParseErrorKind::Expecting("hello".to_string()));
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
}
}

View File

@ -71,15 +71,15 @@ 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.cursor;
let start = reader.cursor();
if parse_json_number(&mut reader).is_ok() {
return Ok(s);
}
reader.cursor = start;
reader.seek(start);
if parse_json_boolean(&mut reader).is_ok() {
return Ok(s);
}
reader.cursor = start;
reader.seek(start);
if parse_json_null(&mut reader).is_ok() {
return Ok(s);
}

View File

@ -38,12 +38,12 @@ pub fn optional<T, E>(f: ParseFunc<T, E>, reader: &mut Reader) -> Result<Option<
where
E: ParseError,
{
let start = reader.cursor;
let start = reader.cursor();
match f(reader) {
Ok(r) => Ok(Some(r)),
Err(e) => {
if e.is_recoverable() {
reader.cursor = start;
reader.seek(start);
Ok(None)
} else {
Err(e)
@ -81,7 +81,7 @@ where
{
let mut v = Vec::new();
loop {
let initial_state = reader.cursor;
let initial_state = reader.cursor();
if reader.is_eof() {
return Ok(v);
}
@ -92,8 +92,7 @@ where
}
Err(e) => {
return if e.is_recoverable() {
reader.cursor.pos = initial_state.pos;
reader.cursor.offset = initial_state.offset;
reader.seek(initial_state);
Ok(v)
} else {
Err(e)
@ -112,15 +111,14 @@ where
Ok(first) => {
let mut v = vec![first];
loop {
let initial_state = reader.cursor;
let initial_state = reader.cursor();
match f(reader) {
Ok(r) => {
v.push(r);
}
Err(e) => {
return if e.is_recoverable() {
reader.cursor.pos = initial_state.pos;
reader.cursor.offset = initial_state.offset;
reader.seek(initial_state);
Ok(v)
} else {
Err(e)
@ -141,13 +139,13 @@ where
E: ParseError,
{
for (pos, f) in fs.iter().enumerate() {
let start = reader.cursor;
let start = reader.cursor();
if pos == fs.len() - 1 {
return f(reader);
}
match f(reader) {
Err(err) if err.is_recoverable() => {
reader.cursor = start;
reader.seek(start);
continue;
}
x => return x,

View File

@ -31,7 +31,7 @@ pub fn parse(reader: &mut Reader) -> Vec<u8> {
if !pad.is_empty() {
break;
}
let save = reader.cursor;
let save = reader.cursor();
match reader.read() {
None => {
break;
@ -39,7 +39,7 @@ pub fn parse(reader: &mut Reader) -> Vec<u8> {
Some(' ') | Some('\n') | Some('\t') => {}
Some(c) => match value(c) {
None => {
reader.cursor = save;
reader.seek(save);
break;
}
Some(v) => {
@ -142,13 +142,13 @@ fn padding(reader: &mut Reader) -> String {
// consume padding can not fail
let mut buf = String::new();
loop {
let save = reader.cursor;
let save = reader.cursor();
match reader.read() {
Some('=') => {
buf.push('=');
}
_ => {
reader.cursor = save;
reader.seek(save);
break;
}
}
@ -183,27 +183,27 @@ mod tests {
fn test_decode_one_block() {
let mut reader = Reader::new("");
assert_eq!(parse(&mut reader), vec![] as Vec<u8>);
assert_eq!(reader.cursor.offset, 0);
assert_eq!(reader.cursor().offset, 0);
let mut reader = Reader::new("AA==;");
assert_eq!(parse(&mut reader), vec![0]);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
let mut reader = Reader::new("AA");
assert_eq!(parse(&mut reader), vec![0]);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("AA;");
assert_eq!(parse(&mut reader), vec![0]);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("TWE=;");
assert_eq!(parse(&mut reader), vec![77, 97]);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
let mut reader = Reader::new("TWFu;");
assert_eq!(parse(&mut reader), vec![77, 97, 110]);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
}
/*
@ -246,7 +246,7 @@ mod tests {
fn test_decode_with_whitespace() {
let mut reader = Reader::new("TW E=\n;");
assert_eq!(parse(&mut reader), vec![77, 97]);
assert_eq!(reader.cursor.offset, 5);
assert_eq!(reader.cursor().offset, 5);
}
#[test]

View File

@ -105,7 +105,7 @@ mod tests {
],
})
);
assert_eq!(reader.cursor.offset, 7);
assert_eq!(reader.cursor().offset, 7);
let mut reader = Reader::new("{ } ");
assert_eq!(
@ -115,14 +115,14 @@ mod tests {
elements: vec![],
})
);
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
let mut reader = Reader::new("true");
assert_eq!(
bytes(&mut reader).unwrap(),
Bytes::Json(JsonValue::Boolean(true))
);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
let mut reader = Reader::new("\"\" x");
assert_eq!(
@ -133,7 +133,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 2), Pos::new(1, 2)),
}))
);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
}
#[test]
@ -202,6 +202,6 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 6))
})
);
assert_eq!(reader.cursor.offset, 5);
assert_eq!(reader.cursor().offset, 5);
}
}

View File

@ -24,7 +24,7 @@ use crate::parser::ParseResult;
use crate::reader::Reader;
pub fn cookiepath(reader: &mut Reader) -> ParseResult<CookiePath> {
let start = reader.cursor.pos;
let start = reader.cursor().pos;
// We create a specialized reader for the templated, error and created structures are
// relative tho the main reader.
@ -49,7 +49,7 @@ fn cookiepath_attribute(reader: &mut Reader) -> ParseResult<CookieAttribute> {
}
fn cookiepath_attribute_name(reader: &mut Reader) -> ParseResult<CookieAttributeName> {
let start = reader.cursor.pos;
let start = reader.cursor().pos;
let s = reader.read_while(|c| c.is_alphabetic() || *c == '-');
match s.to_lowercase().as_str() {
"value" => Ok(CookieAttributeName::Value(s)),
@ -91,7 +91,7 @@ mod tests {
attribute: None,
}
);
assert_eq!(reader.cursor.offset, 7);
assert_eq!(reader.cursor().offset, 7);
}
#[test]
@ -121,7 +121,7 @@ mod tests {
}),
}
);
assert_eq!(reader.cursor.offset, 15);
assert_eq!(reader.cursor().offset, 15);
}
#[test]
@ -161,7 +161,7 @@ mod tests {
}),
}
);
assert_eq!(reader.cursor.offset, 16);
assert_eq!(reader.cursor().offset, 16);
}
#[test]
@ -206,14 +206,14 @@ mod tests {
cookiepath_attribute_name(&mut reader).unwrap(),
CookieAttributeName::Domain("Domain".to_string())
);
assert_eq!(reader.cursor.offset, 6);
assert_eq!(reader.cursor().offset, 6);
let mut reader = Reader::new("domain");
assert_eq!(
cookiepath_attribute_name(&mut reader).unwrap(),
CookieAttributeName::Domain("domain".to_string())
);
assert_eq!(reader.cursor.offset, 6);
assert_eq!(reader.cursor().offset, 6);
let mut reader = Reader::new("unknown");
let error = cookiepath_attribute_name(&mut reader).err().unwrap();

View File

@ -51,7 +51,7 @@ pub fn parse2(reader: &mut Reader) -> ParseResult<Expr> {
}
fn variable_name(reader: &mut Reader) -> ParseResult<Variable> {
let start = reader.cursor;
let start = reader.cursor();
let name = reader.read_while(|c| c.is_alphanumeric() || *c == '_' || *c == '-');
if name.is_empty() {
return Err(ParseError::new(
@ -62,7 +62,7 @@ fn variable_name(reader: &mut Reader) -> ParseResult<Variable> {
}
Ok(Variable {
name,
source_info: SourceInfo::new(start.pos, reader.cursor.pos),
source_info: SourceInfo::new(start.pos, reader.cursor().pos),
})
}

View File

@ -29,11 +29,11 @@ use crate::reader::Reader;
/// This is very similar to the behaviour in a standard shell.
///
pub fn parse(reader: &mut Reader) -> ParseResult<Template> {
let start = reader.cursor;
let start = reader.cursor();
let mut elements = vec![];
loop {
let start = reader.cursor;
let start = reader.cursor();
match template(reader) {
Ok(expr) => {
let element = TemplateElement::Expression(expr);
@ -45,9 +45,7 @@ pub fn parse(reader: &mut Reader) -> ParseResult<Template> {
if value.is_empty() {
break;
}
let encoded: String = reader.buffer[start.offset..reader.cursor.offset]
.iter()
.collect();
let encoded = reader.peek_back(start.offset);
let element = TemplateElement::String { value, encoded };
elements.push(element);
} else {
@ -69,7 +67,7 @@ pub fn parse(reader: &mut Reader) -> ParseResult<Template> {
}
}
let end = reader.cursor;
let end = reader.cursor();
Ok(Template {
delimiter: None,
elements,
@ -107,12 +105,12 @@ fn filename_content(reader: &mut Reader) -> ParseResult<String> {
fn filename_text(reader: &mut Reader) -> String {
let mut s = String::new();
loop {
let save = reader.cursor;
let save = reader.cursor();
match reader.read() {
None => break,
Some(c) => {
if ['#', ';', '{', '}', ' ', '\n', '\\'].contains(&c) {
reader.cursor = save;
reader.seek(save);
break;
} else {
s.push(c);
@ -125,7 +123,7 @@ fn filename_text(reader: &mut Reader) -> String {
fn filename_escaped_char(reader: &mut Reader) -> ParseResult<char> {
try_literal("\\", reader)?;
let start = reader.cursor;
let start = reader.cursor();
match reader.read() {
Some('\\') => Ok('\\'),
Some('b') => Ok('\x08'),
@ -166,7 +164,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 14)),
}
);
assert_eq!(reader.cursor.offset, 13);
assert_eq!(reader.cursor().offset, 13);
let mut reader = Reader::new("data.bin");
assert_eq!(
@ -181,7 +179,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 9)),
}
);
assert_eq!(reader.cursor.offset, 8);
assert_eq!(reader.cursor().offset, 8);
}
#[test]
@ -198,7 +196,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 19)),
}
);
assert_eq!(reader.cursor.offset, 18);
assert_eq!(reader.cursor().offset, 18);
}
#[test]
@ -215,7 +213,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 11)),
}
);
assert_eq!(reader.cursor.offset, 10);
assert_eq!(reader.cursor().offset, 10);
}
#[test]

View File

@ -30,11 +30,11 @@ use crate::reader::Reader;
/// While in the standard filename parser, you can not escape this character at all.
///
pub fn parse(reader: &mut Reader) -> ParseResult<Template> {
let start = reader.cursor;
let start = reader.cursor();
let mut elements = vec![];
loop {
let start = reader.cursor;
let start = reader.cursor();
match template(reader) {
Ok(expr) => {
let element = TemplateElement::Expression(expr);
@ -46,9 +46,7 @@ pub fn parse(reader: &mut Reader) -> ParseResult<Template> {
if value.is_empty() {
break;
}
let encoded: String = reader.buffer[start.offset..reader.cursor.offset]
.iter()
.collect();
let encoded = reader.peek_back(start.offset);
let element = TemplateElement::String { value, encoded };
elements.push(element);
} else {
@ -70,7 +68,7 @@ pub fn parse(reader: &mut Reader) -> ParseResult<Template> {
}
}
let end = reader.cursor;
let end = reader.cursor();
Ok(Template {
delimiter: None,
elements,
@ -113,12 +111,12 @@ fn filename_password_content(reader: &mut Reader) -> ParseResult<String> {
fn filename_password_text(reader: &mut Reader) -> String {
let mut s = String::new();
loop {
let save = reader.cursor;
let save = reader.cursor();
match reader.read() {
None => break,
Some(c) => {
if ['#', ';', '{', '}', '\n', '\\'].contains(&c) {
reader.cursor = save;
reader.seek(save);
break;
} else {
s.push(c);
@ -131,7 +129,7 @@ fn filename_password_text(reader: &mut Reader) -> String {
fn filename_password_escaped_char(reader: &mut Reader) -> ParseResult<char> {
try_literal("\\", reader)?;
let start = reader.cursor;
let start = reader.cursor();
match reader.read() {
Some('\\') => Ok('\\'),
Some('b') => Ok('\x08'),
@ -173,6 +171,6 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 19)),
}
);
assert_eq!(reader.cursor.offset, 18);
assert_eq!(reader.cursor().offset, 18);
}
}

View File

@ -27,7 +27,7 @@ use crate::reader::Reader;
pub fn filters(reader: &mut Reader) -> ParseResult<Vec<(Whitespace, Filter)>> {
let mut filters = vec![];
loop {
let save = reader.cursor;
let save = reader.cursor();
let space = zero_or_more_spaces(reader)?;
if space.value.is_empty() {
break;
@ -38,7 +38,7 @@ pub fn filters(reader: &mut Reader) -> ParseResult<Vec<(Whitespace, Filter)>> {
}
Err(e) => {
if e.recoverable {
reader.cursor = save;
reader.seek(save);
break;
} else {
return Err(e);
@ -50,7 +50,7 @@ pub fn filters(reader: &mut Reader) -> ParseResult<Vec<(Whitespace, Filter)>> {
}
pub fn filter(reader: &mut Reader) -> ParseResult<Filter> {
let start = reader.cursor.pos;
let start = reader.cursor();
let value = choice(
&[
count_filter,
@ -84,8 +84,11 @@ pub fn filter(reader: &mut Reader) -> ParseResult<Filter> {
e
}
})?;
let end = reader.cursor.pos;
let source_info = SourceInfo { start, end };
let end = reader.cursor();
let source_info = SourceInfo {
start: start.pos,
end: end.pos,
};
Ok(Filter { source_info, value })
}

View File

@ -43,7 +43,7 @@ fn parse_in_json(reader: &mut Reader) -> ParseResult<JsonValue> {
if let Some(c) = reader.peek() {
if c == ',' {
let kind = ParseErrorKind::Json(JsonErrorVariant::EmptyElement);
return Err(ParseError::new(reader.cursor.pos, false, kind));
return Err(ParseError::new(reader.cursor().pos, false, kind));
}
}
match parse(reader) {
@ -82,7 +82,7 @@ fn string_template(reader: &mut Reader) -> ParseResult<Template> {
try_literal("\"", reader)?;
let delimiter = Some('"');
let mut chars = vec![];
let start = reader.cursor.pos;
let start = reader.cursor();
loop {
if reader.peek() == Some('"') || reader.is_eof() {
break;
@ -90,10 +90,10 @@ fn string_template(reader: &mut Reader) -> ParseResult<Template> {
let char = any_char(reader)?;
chars.push(char);
}
let end = reader.cursor.pos;
let end = reader.cursor();
let encoded_string = EncodedString {
source_info: SourceInfo { start, end },
source_info: SourceInfo::new(start.pos, end.pos),
chars,
};
literal("\"", reader)?;
@ -102,18 +102,18 @@ fn string_template(reader: &mut Reader) -> ParseResult<Template> {
let template = Template {
delimiter,
elements,
source_info: SourceInfo { start, end },
source_info: SourceInfo::new(start.pos, end.pos),
};
Ok(template)
}
fn any_char(reader: &mut Reader) -> ParseResult<(char, String, Pos)> {
let start = reader.cursor;
let start = reader.cursor();
match escape_char(reader) {
Ok(c) => Ok((c, reader.peek_back(start.offset), start.pos)),
Err(e) => {
if e.recoverable {
reader.cursor = start;
reader.seek(start);
match reader.read() {
None => {
let kind = ParseErrorKind::Expecting {
@ -141,7 +141,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.cursor;
let start = reader.cursor();
match reader.read() {
Some('"') => Ok('"'),
Some('\\') => Ok('\\'),
@ -161,21 +161,21 @@ fn escape_char(reader: &mut Reader) -> ParseResult<char> {
}
fn unicode(reader: &mut Reader) -> ParseResult<char> {
let start = reader.cursor.pos;
let start = reader.cursor();
let cp1 = hex_value(reader)?;
let cp = if is_surrogate(cp1) {
literal("\\u", reader)?;
let start = reader.cursor.pos;
let start = reader.cursor();
let cp2 = hex_value(reader)?;
match cp_surrogate_pair(cp1, cp2) {
None => return Err(ParseError::new(start, false, ParseErrorKind::Unicode)),
None => return Err(ParseError::new(start.pos, false, ParseErrorKind::Unicode)),
Some(cp) => cp,
}
} else {
cp1
};
let c = match char::from_u32(cp) {
None => return Err(ParseError::new(start, false, ParseErrorKind::Unicode)),
None => return Err(ParseError::new(start.pos, false, ParseErrorKind::Unicode)),
Some(c) => c,
};
Ok(c)
@ -212,7 +212,7 @@ fn hex_value(reader: &mut Reader) -> ParseResult<u32> {
}
pub fn number_value(reader: &mut Reader) -> ParseResult<JsonValue> {
let start = reader.cursor;
let start = reader.cursor();
let sign = match try_literal("-", reader) {
Err(_) => String::new(),
@ -241,7 +241,7 @@ pub fn number_value(reader: &mut Reader) -> ParseResult<JsonValue> {
let kind = ParseErrorKind::Expecting {
value: "digits".to_string(),
};
return Err(ParseError::new(reader.cursor.pos, false, kind));
return Err(ParseError::new(reader.cursor().pos, false, kind));
} else {
format!(".{digits}")
}
@ -295,13 +295,13 @@ fn list_value(reader: &mut Reader) -> ParseResult<JsonValue> {
}
// The reader advances after literal(","), so this saves its position to report an
// error in case it happens.
let save = reader.cursor.pos;
let save = reader.cursor();
literal(",", reader)?;
// If there is one more comma, e.g. [1, 2,], it's better to report to the user because
// this occurrence is common.
if reader.peek_ignoring_whitespace() == Some(']') {
let kind = ParseErrorKind::Json(JsonErrorVariant::TrailingComma);
return Err(ParseError::new(save, false, kind));
return Err(ParseError::new(save.pos, false, kind));
}
let element = list_element(reader)?;
elements.push(element);
@ -342,13 +342,13 @@ pub fn object_value(reader: &mut Reader) -> ParseResult<JsonValue> {
}
// The reader advances after literal(","), so this saves its position to report an
// error in case it happens.
let save = reader.cursor.pos;
let save = reader.cursor();
literal(",", reader)?;
// If there is one more comma, e.g. {"a": "b",}, it's better to report to the user
// because this occurrence is common.
if reader.peek_ignoring_whitespace() == Some('}') {
let kind = ParseErrorKind::Json(JsonErrorVariant::TrailingComma);
return Err(ParseError::new(save, false, kind));
return Err(ParseError::new(save.pos, false, kind));
}
let element = object_element(reader)?;
elements.push(element);
@ -374,7 +374,7 @@ fn object_element(reader: &mut Reader) -> ParseResult<JsonObjectElement> {
//literal("\"", reader)?;
let space1 = whitespace(reader);
literal(":", reader)?;
let save = reader.cursor.pos;
let save = reader.cursor();
let space2 = whitespace(reader);
// Checks if there is no element after ':'. In this case, a special error must be reported
// because this is a common occurrence.
@ -382,7 +382,7 @@ fn object_element(reader: &mut Reader) -> ParseResult<JsonObjectElement> {
// Comparing to None because `next_char` can be EOF.
if next_char == Some('}') || next_char.is_none() {
let kind = ParseErrorKind::Json(JsonErrorVariant::EmptyElement);
return Err(ParseError::new(save, false, kind));
return Err(ParseError::new(save.pos, false, kind));
}
let value = parse_in_json(reader)?;
let space3 = whitespace(reader);
@ -430,7 +430,7 @@ mod tests {
fn test_null_value() {
let mut reader = Reader::new("null");
assert_eq!(null_value(&mut reader).unwrap(), JsonValue::Null);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
let mut reader = Reader::new("true");
let error = null_value(&mut reader).err().unwrap();
@ -451,7 +451,7 @@ mod tests {
boolean_value(&mut reader).unwrap(),
JsonValue::Boolean(true)
);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
let mut reader = Reader::new("1");
let error = boolean_value(&mut reader).err().unwrap();
@ -508,11 +508,11 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 2), Pos::new(1, 2)),
})
);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("\"Hello\\u0020{{name}}!\"");
assert_eq!(string_value(&mut reader).unwrap(), json_hello_world_value());
assert_eq!(reader.cursor.offset, 22);
assert_eq!(reader.cursor().offset, 22);
let mut reader = Reader::new("\"{}\"");
assert_eq!(
@ -526,7 +526,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 2), Pos::new(1, 4)),
})
);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
}
#[test]
@ -572,35 +572,35 @@ mod tests {
any_char(&mut reader).unwrap(),
('a', "a".to_string(), Pos { line: 1, column: 1 })
);
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
let mut reader = Reader::new(" ");
assert_eq!(
any_char(&mut reader).unwrap(),
(' ', " ".to_string(), Pos { line: 1, column: 1 })
);
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
let mut reader = Reader::new("\\u0020 ");
assert_eq!(
any_char(&mut reader).unwrap(),
(' ', "\\u0020".to_string(), Pos { line: 1, column: 1 })
);
assert_eq!(reader.cursor.offset, 6);
assert_eq!(reader.cursor().offset, 6);
let mut reader = Reader::new("\\t");
assert_eq!(
any_char(&mut reader).unwrap(),
('\t', "\\t".to_string(), Pos { line: 1, column: 1 })
);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("#");
assert_eq!(
any_char(&mut reader).unwrap(),
('#', "#".to_string(), Pos { line: 1, column: 1 })
);
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
}
#[test]
@ -620,11 +620,11 @@ mod tests {
fn test_escape_char() {
let mut reader = Reader::new("\\n");
assert_eq!(escape_char(&mut reader).unwrap(), '\n');
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("\\u000a");
assert_eq!(escape_char(&mut reader).unwrap(), '\n');
assert_eq!(reader.cursor.offset, 6);
assert_eq!(reader.cursor().offset, 6);
let mut reader = Reader::new("x");
let error = escape_char(&mut reader).err().unwrap();
@ -636,22 +636,22 @@ mod tests {
}
);
assert!(error.recoverable);
assert_eq!(reader.cursor.offset, 0);
assert_eq!(reader.cursor().offset, 0);
}
#[test]
fn test_unicode() {
let mut reader = Reader::new("000a");
assert_eq!(unicode(&mut reader).unwrap(), '\n');
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
let mut reader = Reader::new("c350");
assert_eq!(unicode(&mut reader).unwrap(), '썐');
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
let mut reader = Reader::new("d83c\\udf78");
assert_eq!(unicode(&mut reader).unwrap(), '🍸');
assert_eq!(reader.cursor.offset, 10);
assert_eq!(reader.cursor().offset, 10);
let mut reader = Reader::new("d800");
let error = unicode(&mut reader).unwrap_err();
@ -693,49 +693,49 @@ mod tests {
number_value(&mut reader).unwrap(),
JsonValue::Number("100".to_string())
);
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
let mut reader = Reader::new("1.333");
assert_eq!(
number_value(&mut reader).unwrap(),
JsonValue::Number("1.333".to_string())
);
assert_eq!(reader.cursor.offset, 5);
assert_eq!(reader.cursor().offset, 5);
let mut reader = Reader::new("-1");
assert_eq!(
number_value(&mut reader).unwrap(),
JsonValue::Number("-1".to_string())
);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("00");
assert_eq!(
number_value(&mut reader).unwrap(),
JsonValue::Number("0".to_string())
);
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
let mut reader = Reader::new("1e0");
assert_eq!(
number_value(&mut reader).unwrap(),
JsonValue::Number("1e0".to_string())
);
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
let mut reader = Reader::new("1e005");
assert_eq!(
number_value(&mut reader).unwrap(),
JsonValue::Number("1e005".to_string())
);
assert_eq!(reader.cursor.offset, 5);
assert_eq!(reader.cursor().offset, 5);
let mut reader = Reader::new("1e-005");
assert_eq!(
number_value(&mut reader).unwrap(),
JsonValue::Number("1e-005".to_string())
);
assert_eq!(reader.cursor.offset, 6);
assert_eq!(reader.cursor().offset, 6);
}
#[test]
@ -783,7 +783,7 @@ mod tests {
}
})
);
assert_eq!(reader.cursor.offset, 5);
assert_eq!(reader.cursor().offset, 5);
}
#[test]
@ -796,7 +796,7 @@ mod tests {
elements: vec![]
}
);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("[ ]");
assert_eq!(
@ -806,7 +806,7 @@ mod tests {
elements: vec![]
}
);
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
let mut reader = Reader::new("[true, false]");
assert_eq!(
@ -827,7 +827,7 @@ mod tests {
],
}
);
assert_eq!(reader.cursor.offset, 13);
assert_eq!(reader.cursor().offset, 13);
}
#[test]
@ -864,7 +864,7 @@ mod tests {
space1: String::new(),
}
);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
}
#[test]
@ -877,7 +877,7 @@ mod tests {
elements: vec![]
}
);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("{ }");
assert_eq!(
@ -887,7 +887,7 @@ mod tests {
elements: vec![]
}
);
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
let mut reader = Reader::new("{\n \"a\": true\n}");
assert_eq!(
@ -911,7 +911,7 @@ mod tests {
}],
}
);
assert_eq!(reader.cursor.offset, 15);
assert_eq!(reader.cursor().offset, 15);
let mut reader = Reader::new("true");
let error = object_value(&mut reader).err().unwrap();
@ -958,7 +958,7 @@ mod tests {
space3: String::new(),
}
);
assert_eq!(reader.cursor.offset, 9);
assert_eq!(reader.cursor().offset, 9);
}
#[test]
@ -988,14 +988,14 @@ mod tests {
fn test_whitespace() {
let mut reader = Reader::new("");
assert_eq!(whitespace(&mut reader), String::new());
assert_eq!(reader.cursor.offset, 0);
assert_eq!(reader.cursor().offset, 0);
let mut reader = Reader::new(" x");
assert_eq!(whitespace(&mut reader), " ".to_string());
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
let mut reader = Reader::new("\n x");
assert_eq!(whitespace(&mut reader), "\n ".to_string());
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
}
}

View File

@ -23,7 +23,7 @@ use crate::parser::{string, ParseResult};
use crate::reader::Reader;
pub fn parse(reader: &mut Reader) -> ParseResult<Template> {
let start = reader.cursor;
let start = reader.cursor();
let mut elements = vec![];
loop {
@ -38,9 +38,7 @@ pub fn parse(reader: &mut Reader) -> ParseResult<Template> {
if value.is_empty() {
break;
}
let encoded: String = reader.buffer[start.offset..reader.cursor.offset]
.iter()
.collect();
let encoded = reader.peek_back(start.offset);
let element = TemplateElement::String { value, encoded };
elements.push(element);
} else {
@ -64,14 +62,11 @@ pub fn parse(reader: &mut Reader) -> ParseResult<Template> {
}
}
let end = reader.cursor;
let end = reader.cursor();
Ok(Template {
delimiter: None,
elements,
source_info: SourceInfo {
start: start.pos,
end: end.pos,
},
source_info: SourceInfo::new(start.pos, end.pos),
})
}
@ -102,7 +97,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.cursor;
let save = reader.cursor();
match reader.read() {
None => break,
Some(c) => {
@ -117,7 +112,7 @@ fn key_string_text(reader: &mut Reader) -> String {
{
s.push(c);
} else {
reader.cursor = save;
reader.seek(save);
break;
}
}
@ -129,7 +124,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.cursor;
let start = reader.cursor();
match reader.read() {
Some('#') => Ok('#'),
Some(':') => Ok(':'),
@ -168,7 +163,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 6)),
}
);
assert_eq!(reader.cursor.offset, 5);
assert_eq!(reader.cursor().offset, 5);
let mut reader = Reader::new("$top:");
assert_eq!(
@ -182,7 +177,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 5)),
}
);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
let mut reader = Reader::new("key\\u{20}\\u{3a} :");
assert_eq!(
@ -196,7 +191,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 16)),
}
);
assert_eq!(reader.cursor.offset, 15);
assert_eq!(reader.cursor().offset, 15);
let mut reader = Reader::new("values\\u{5b}0\\u{5d} :");
assert_eq!(
@ -210,7 +205,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 20)),
}
);
assert_eq!(reader.cursor.offset, 19);
assert_eq!(reader.cursor().offset, 19);
let mut reader = Reader::new("values[0] :");
assert_eq!(
@ -224,7 +219,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 10)),
}
);
assert_eq!(reader.cursor.offset, 9);
assert_eq!(reader.cursor().offset, 9);
let mut reader = Reader::new("\\u{5b}0\\u{5d}");
assert_eq!(
@ -238,7 +233,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 14)),
}
);
assert_eq!(reader.cursor.offset, 13);
assert_eq!(reader.cursor().offset, 13);
}
#[test]
@ -257,7 +252,7 @@ mod tests {
let mut reader = Reader::new("[0]:");
let error = parse(&mut reader).err().unwrap();
assert!(!error.recoverable);
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
let mut reader = Reader::new("\\l");
let error = parse(&mut reader).err().unwrap();
@ -285,18 +280,18 @@ mod tests {
fn test_key_string_text() {
let mut reader = Reader::new("aaa\\:");
assert_eq!(key_string_text(&mut reader), "aaa");
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
}
#[test]
fn test_key_string_escaped_char() {
let mut reader = Reader::new("\\u{0a}");
assert_eq!(key_string_escaped_char(&mut reader).unwrap(), '\n');
assert_eq!(reader.cursor.offset, 6);
assert_eq!(reader.cursor().offset, 6);
let mut reader = Reader::new("\\:");
assert_eq!(key_string_escaped_char(&mut reader).unwrap(), ':');
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("x");
let error = key_string_escaped_char(&mut reader).err().unwrap();
@ -308,6 +303,6 @@ mod tests {
}
);
assert!(error.recoverable);
assert_eq!(reader.cursor.offset, 0);
assert_eq!(reader.cursor().offset, 0);
}
}

View File

@ -24,7 +24,7 @@ use crate::reader::Reader;
pub fn multiline_string(reader: &mut Reader) -> ParseResult<MultilineString> {
try_literal("```", reader)?;
let save = reader.cursor;
let save = reader.cursor();
match choice(&[json_text, xml_text, graphql, plain_text], reader) {
Ok(multi) => Ok(multi),
@ -46,7 +46,7 @@ pub fn multiline_string(reader: &mut Reader) -> ParseResult<MultilineString> {
if let ParseErrorKind::GraphQlVariables = err.kind {
return Err(err);
}
reader.cursor = save;
reader.seek(save);
let value = oneline_string_value(reader)?;
Ok(MultilineString::OneLineText(value))
}
@ -82,13 +82,13 @@ fn graphql(reader: &mut Reader) -> ParseResult<MultilineString> {
let mut chars = vec![];
let start = reader.cursor.pos;
let start = reader.cursor();
while reader.peek_n(3) != "```" && !reader.is_eof() {
let pos = reader.cursor.pos;
let pos = reader.cursor().pos;
let c = reader.read().unwrap();
chars.push((c, c.to_string(), pos));
if c == '\n' {
let end = reader.cursor.pos;
let end = reader.cursor();
let variables = optional(graphql_variables, reader)?;
match variables {
None => continue,
@ -96,7 +96,7 @@ fn graphql(reader: &mut Reader) -> ParseResult<MultilineString> {
literal("```", reader)?;
let encoded_string = template::EncodedString {
source_info: SourceInfo { start, end },
source_info: SourceInfo::new(start.pos, end.pos),
chars: chars.clone(),
};
@ -104,7 +104,7 @@ fn graphql(reader: &mut Reader) -> ParseResult<MultilineString> {
let template = Template {
delimiter: None,
elements,
source_info: SourceInfo { start, end },
source_info: SourceInfo::new(start.pos, end.pos),
};
return Ok(MultilineString::GraphQl(GraphQl {
@ -117,11 +117,11 @@ fn graphql(reader: &mut Reader) -> ParseResult<MultilineString> {
}
}
}
let end = reader.cursor.pos;
let end = reader.cursor();
literal("```", reader)?;
let encoded_string = template::EncodedString {
source_info: SourceInfo { start, end },
source_info: SourceInfo::new(start.pos, end.pos),
chars,
};
@ -129,7 +129,7 @@ fn graphql(reader: &mut Reader) -> ParseResult<MultilineString> {
let template = Template {
delimiter: None,
elements,
source_info: SourceInfo { start, end },
source_info: SourceInfo::new(start.pos, end.pos),
};
Ok(MultilineString::GraphQl(GraphQl {
@ -141,14 +141,14 @@ fn graphql(reader: &mut Reader) -> ParseResult<MultilineString> {
}
fn whitespace(reader: &mut Reader) -> ParseResult<Whitespace> {
let start = reader.cursor;
let start = reader.cursor();
match reader.read() {
None => Err(ParseError::new(start.pos, true, ParseErrorKind::Space)),
Some(c) => {
if c == ' ' || c == '\t' || c == '\n' || c == '\r' {
Ok(Whitespace {
value: c.to_string(),
source_info: SourceInfo::new(start.pos, reader.cursor.pos),
source_info: SourceInfo::new(start.pos, reader.cursor().pos),
})
} else {
Err(ParseError::new(start.pos, true, ParseErrorKind::Space))
@ -158,13 +158,13 @@ fn whitespace(reader: &mut Reader) -> ParseResult<Whitespace> {
}
fn zero_or_more_whitespaces(reader: &mut Reader) -> ParseResult<Whitespace> {
let start = reader.cursor;
let start = reader.cursor();
match zero_or_more(whitespace, reader) {
Ok(v) => {
let s = v.iter().map(|x| x.value.clone()).collect();
Ok(Whitespace {
value: s,
source_info: SourceInfo::new(start.pos, reader.cursor.pos),
source_info: SourceInfo::new(start.pos, reader.cursor().pos),
})
}
Err(e) => Err(e),
@ -174,7 +174,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.cursor;
let start = reader.cursor();
let object = object_value(reader);
let value = match object {
Ok(obj) => obj,
@ -208,17 +208,17 @@ fn plain_text(reader: &mut Reader) -> ParseResult<MultilineString> {
fn multiline_string_value(reader: &mut Reader) -> ParseResult<Template> {
let mut chars = vec![];
let start = reader.cursor.pos;
let start = reader.cursor();
while reader.peek_n(3) != "```" && !reader.is_eof() {
let pos = reader.cursor.pos;
let pos = reader.cursor().pos;
let c = reader.read().unwrap();
chars.push((c, c.to_string(), pos));
}
let end = reader.cursor.pos;
let end = reader.cursor();
literal("```", reader)?;
let encoded_string = template::EncodedString {
source_info: SourceInfo { start, end },
source_info: SourceInfo::new(start.pos, end.pos),
chars,
};
@ -227,27 +227,27 @@ fn multiline_string_value(reader: &mut Reader) -> ParseResult<Template> {
Ok(Template {
delimiter: None,
elements,
source_info: SourceInfo { start, end },
source_info: SourceInfo::new(start.pos, end.pos),
})
}
fn oneline_string_value(reader: &mut Reader) -> ParseResult<Template> {
let mut chars = vec![];
let start = reader.cursor.pos;
let start = reader.cursor();
while reader.peek_n(3) != "```" && !reader.is_eof() {
let pos = reader.cursor.pos;
let pos = reader.cursor().pos;
let c = reader.read().unwrap();
if c == '\n' {
return Err(ParseError::new(start, false, ParseErrorKind::Multiline));
return Err(ParseError::new(start.pos, false, ParseErrorKind::Multiline));
}
chars.push((c, c.to_string(), pos));
}
let end = reader.cursor.pos;
let end = reader.cursor();
literal("```", reader)?;
let encoded_string = template::EncodedString {
source_info: SourceInfo { start, end },
source_info: SourceInfo::new(start.pos, end.pos),
chars,
};
@ -256,7 +256,7 @@ fn oneline_string_value(reader: &mut Reader) -> ParseResult<Template> {
Ok(Template {
delimiter: None,
elements,
source_info: SourceInfo { start, end },
source_info: SourceInfo::new(start.pos, end.pos),
})
}
@ -606,7 +606,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 1)),
}
);
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
let mut reader = Reader::new("hello```");
assert_eq!(
@ -620,7 +620,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 6)),
}
);
assert_eq!(reader.cursor.offset, 8);
assert_eq!(reader.cursor().offset, 8);
}
#[test]

View File

@ -22,7 +22,7 @@ use crate::parser::ParseResult;
use crate::reader::Reader;
pub fn natural(reader: &mut Reader) -> ParseResult<u64> {
let start = reader.cursor;
let start = reader.cursor();
if reader.is_eof() {
let kind = ParseErrorKind::Expecting {
@ -38,7 +38,7 @@ pub fn natural(reader: &mut Reader) -> ParseResult<u64> {
return Err(ParseError::new(start.pos, true, kind));
}
let save = reader.cursor;
let save = reader.cursor();
let s = reader.read_while(|c| c.is_ascii_digit());
// if the first digit is zero, you should not have any more digits
@ -69,7 +69,7 @@ pub fn integer(reader: &mut Reader) -> ParseResult<i64> {
}
pub fn number(reader: &mut Reader) -> ParseResult<Number> {
let start = reader.cursor;
let start = reader.cursor();
let sign = match try_literal("-", reader) {
Err(_) => "",
Ok(_) => "-",
@ -79,11 +79,11 @@ pub fn number(reader: &mut Reader) -> ParseResult<Number> {
let kind = ParseErrorKind::Expecting {
value: "number".to_string(),
};
return Err(ParseError::new(reader.cursor.pos, true, kind));
return Err(ParseError::new(reader.cursor().pos, true, kind));
// if the first digit is zero, you should not have any more digits
} else if integer_digits.len() > 1 && integer_digits.starts_with('0') {
let save = reader.cursor;
let save = reader.cursor();
let kind = ParseErrorKind::Expecting {
value: String::from("natural"),
};
@ -92,7 +92,7 @@ pub fn number(reader: &mut Reader) -> ParseResult<Number> {
// Float
if try_literal(".", reader).is_ok() {
let save = reader.cursor;
let save = reader.cursor();
let decimal_digits = reader.read_while(|c| c.is_ascii_digit());
if decimal_digits.is_empty() {
let kind = ParseErrorKind::Expecting {
@ -131,11 +131,11 @@ mod tests {
fn test_natural() {
let mut reader = Reader::new("0");
assert_eq!(natural(&mut reader).unwrap(), 0);
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
let mut reader = Reader::new("10x");
assert_eq!(natural(&mut reader).unwrap(), 10);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
}
#[test]
@ -178,23 +178,23 @@ mod tests {
fn test_integer() {
let mut reader = Reader::new("0");
assert_eq!(integer(&mut reader).unwrap(), 0);
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
let mut reader = Reader::new("-1");
assert_eq!(integer(&mut reader).unwrap(), -1);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("0");
assert_eq!(number(&mut reader).unwrap(), Number::Integer(0));
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
let mut reader = Reader::new("10x");
assert_eq!(number(&mut reader).unwrap(), Number::Integer(10));
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("-10x");
assert_eq!(number(&mut reader).unwrap(), Number::Integer(-10));
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
}
#[test]
@ -207,7 +207,7 @@ mod tests {
encoded: "1.0".to_string()
})
);
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
let mut reader = Reader::new("-1.0");
assert_eq!(
@ -217,7 +217,7 @@ mod tests {
encoded: "-1.0".to_string()
})
);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
let mut reader = Reader::new("1.1");
assert_eq!(
@ -227,7 +227,7 @@ mod tests {
encoded: "1.1".to_string()
})
);
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
let mut reader = Reader::new("1.100");
assert_eq!(
@ -237,7 +237,7 @@ mod tests {
encoded: "1.100".to_string()
})
);
assert_eq!(reader.cursor.offset, 5);
assert_eq!(reader.cursor().offset, 5);
let mut reader = Reader::new("1.01");
assert_eq!(
@ -247,7 +247,7 @@ mod tests {
encoded: "1.01".to_string()
})
);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
let mut reader = Reader::new("1.010");
assert_eq!(
@ -257,7 +257,7 @@ mod tests {
encoded: "1.010".to_string()
})
);
assert_eq!(reader.cursor.offset, 5);
assert_eq!(reader.cursor().offset, 5);
// provide more digits than necessary
let mut reader = Reader::new("-0.3333333333333333333");
@ -268,7 +268,7 @@ mod tests {
encoded: "-0.3333333333333333333".to_string()
})
);
assert_eq!(reader.cursor.offset, 22);
assert_eq!(reader.cursor().offset, 22);
let mut reader = Reader::new("1000000000000000000000.5");
assert_eq!(
@ -278,7 +278,7 @@ mod tests {
encoded: "1000000000000000000000.5".to_string()
})
);
assert_eq!(reader.cursor.offset, 24);
assert_eq!(reader.cursor().offset, 24);
}
#[test]

View File

@ -29,7 +29,7 @@ use crate::typing::{Repeat, Retry};
pub fn parse(reader: &mut Reader) -> ParseResult<EntryOption> {
let line_terminators = optional_line_terminators(reader)?;
let space0 = zero_or_more_spaces(reader)?;
let start = reader.cursor.pos;
let start = reader.cursor();
// We accept '_' even if there is no option name with this character. We do this to be able to
// enter the parsing of the option name and to have better error description (ex: 'max-redirs'
// vs 'max_redirs').
@ -74,7 +74,7 @@ pub fn parse(reader: &mut Reader) -> ParseResult<EntryOption> {
"very-verbose" => option_very_verbose(reader)?,
_ => {
return Err(ParseError::new(
start,
start.pos,
false,
ParseErrorKind::InvalidOption(option.to_string()),
))
@ -258,7 +258,7 @@ fn option_very_verbose(reader: &mut Reader) -> ParseResult<OptionKind> {
}
fn repeat(reader: &mut Reader) -> ParseResult<Repeat> {
let pos = reader.cursor.pos;
let start = reader.cursor();
let value = non_recover(integer, reader)?;
if value == -1 {
Ok(Repeat::Forever)
@ -268,12 +268,12 @@ fn repeat(reader: &mut Reader) -> ParseResult<Repeat> {
let kind = ParseErrorKind::Expecting {
value: "Expecting a repeat value".to_string(),
};
Err(ParseError::new(pos, false, kind))
Err(ParseError::new(start.pos, false, kind))
}
}
fn retry(reader: &mut Reader) -> ParseResult<Retry> {
let pos = reader.cursor.pos;
let start = reader.cursor();
let value = non_recover(integer, reader)?;
if value == -1 {
Ok(Retry::Infinite)
@ -283,16 +283,16 @@ fn retry(reader: &mut Reader) -> ParseResult<Retry> {
let kind = ParseErrorKind::Expecting {
value: "Expecting a retry value".to_string(),
};
Err(ParseError::new(pos, false, kind))
Err(ParseError::new(start.pos, false, kind))
}
}
fn boolean_option(reader: &mut Reader) -> ParseResult<BooleanOption> {
let start = reader.cursor;
let start = reader.cursor();
match boolean(reader) {
Ok(v) => Ok(BooleanOption::Literal(v)),
Err(_) => {
reader.cursor = start;
reader.seek(start);
let exp = expr::parse(reader).map_err(|e| {
let kind = ParseErrorKind::Expecting {
value: "true|false".to_string(),
@ -305,11 +305,11 @@ fn boolean_option(reader: &mut Reader) -> ParseResult<BooleanOption> {
}
fn natural_option(reader: &mut Reader) -> ParseResult<NaturalOption> {
let start = reader.cursor;
let start = reader.cursor();
match natural(reader) {
Ok(v) => Ok(NaturalOption::Literal(v)),
Err(_) => {
reader.cursor = start;
reader.seek(start);
let exp = expr::parse(reader).map_err(|e| {
let kind = ParseErrorKind::Expecting {
value: "integer".to_string(),
@ -322,11 +322,11 @@ fn natural_option(reader: &mut Reader) -> ParseResult<NaturalOption> {
}
fn repeat_option(reader: &mut Reader) -> ParseResult<RepeatOption> {
let start = reader.cursor;
let start = reader.cursor();
match repeat(reader) {
Ok(v) => Ok(RepeatOption::Literal(v)),
Err(_) => {
reader.cursor = start;
reader.seek(start);
let exp = expr::parse(reader).map_err(|e| {
let kind = ParseErrorKind::Expecting {
value: "integer".to_string(),
@ -339,11 +339,11 @@ fn repeat_option(reader: &mut Reader) -> ParseResult<RepeatOption> {
}
fn retry_option(reader: &mut Reader) -> ParseResult<RetryOption> {
let start = reader.cursor;
let start = reader.cursor();
match retry(reader) {
Ok(v) => Ok(RetryOption::Literal(v)),
Err(_) => {
reader.cursor = start;
reader.seek(start);
let exp = expr::parse(reader).map_err(|e| {
let kind = ParseErrorKind::Expecting {
value: "integer".to_string(),
@ -370,7 +370,7 @@ fn variable_definition(reader: &mut Reader) -> ParseResult<VariableDefinition> {
}
fn variable_name(reader: &mut Reader) -> ParseResult<String> {
let start = reader.cursor;
let start = reader.cursor();
let name = reader.read_while(|c| c.is_alphanumeric() || *c == '_' || *c == '-');
if name.is_empty() {
let kind = ParseErrorKind::Expecting {

View File

@ -47,7 +47,7 @@ fn entry(reader: &mut Reader) -> ParseResult<Entry> {
}
fn request(reader: &mut Reader) -> ParseResult<Request> {
let start = reader.cursor;
let start = reader.cursor();
let line_terminators = optional_line_terminators(reader)?;
let space0 = zero_or_more_spaces(reader)?;
let m = method(reader)?;
@ -58,7 +58,7 @@ fn request(reader: &mut Reader) -> ParseResult<Request> {
let headers = zero_or_more(key_value, reader)?;
let sections = request_sections(reader)?;
let b = optional(body, reader)?;
let source_info = SourceInfo::new(start.pos, reader.cursor.pos);
let source_info = SourceInfo::new(start.pos, reader.cursor().pos);
// Check duplicated section
let mut section_names = vec![];
@ -89,7 +89,7 @@ fn request(reader: &mut Reader) -> ParseResult<Request> {
}
fn response(reader: &mut Reader) -> ParseResult<Response> {
let start = reader.cursor;
let start = reader.cursor();
let line_terminators = optional_line_terminators(reader)?;
let space0 = zero_or_more_spaces(reader)?;
let _version = version(reader)?;
@ -109,7 +109,7 @@ fn response(reader: &mut Reader) -> ParseResult<Response> {
headers,
sections,
body: b,
source_info: SourceInfo::new(start.pos, reader.cursor.pos),
source_info: SourceInfo::new(start.pos, reader.cursor().pos),
})
}
@ -118,9 +118,9 @@ fn method(reader: &mut Reader) -> ParseResult<Method> {
let kind = ParseErrorKind::Method {
name: "<EOF>".to_string(),
};
return Err(ParseError::new(reader.cursor.pos, true, kind));
return Err(ParseError::new(reader.cursor().pos, true, kind));
}
let start = reader.cursor;
let start = reader.cursor();
let name = reader.read_while(|c| c.is_ascii_alphabetic());
if name.is_empty() || name.to_uppercase() != name {
let kind = ParseErrorKind::Method { name };
@ -131,7 +131,7 @@ fn method(reader: &mut Reader) -> ParseResult<Method> {
}
fn version(reader: &mut Reader) -> ParseResult<Version> {
let start = reader.cursor;
let start = reader.cursor();
try_literal("HTTP", reader)?;
let next_c = reader.peek();
@ -148,7 +148,7 @@ fn version(reader: &mut Reader) -> ParseResult<Version> {
if try_literal(s, reader).is_ok() {
return Ok(Version {
value: value.clone(),
source_info: SourceInfo::new(start.pos, reader.cursor.pos),
source_info: SourceInfo::new(start.pos, reader.cursor().pos),
});
}
}
@ -156,25 +156,25 @@ fn version(reader: &mut Reader) -> ParseResult<Version> {
}
Some(' ') | Some('\t') => Ok(Version {
value: VersionAny,
source_info: SourceInfo::new(start.pos, reader.cursor.pos),
source_info: SourceInfo::new(start.pos, reader.cursor().pos),
}),
_ => Err(ParseError::new(start.pos, false, ParseErrorKind::Version)),
}
}
fn status(reader: &mut Reader) -> ParseResult<Status> {
let start = reader.cursor.pos;
let start = reader.cursor();
let value = match try_literal("*", reader) {
Ok(_) => StatusValue::Any,
Err(_) => match natural(reader) {
Ok(value) => StatusValue::Specific(value),
Err(_) => return Err(ParseError::new(start, false, ParseErrorKind::Status)),
Err(_) => return Err(ParseError::new(start.pos, false, ParseErrorKind::Status)),
},
};
let end = reader.cursor.pos;
let end = reader.cursor();
Ok(Status {
value,
source_info: SourceInfo { start, end },
source_info: SourceInfo::new(start.pos, end.pos),
})
}
@ -209,7 +209,7 @@ mod tests {
let mut reader = Reader::new("GET http://google.fr");
let e = entry(&mut reader).unwrap();
assert_eq!(e.request.method, Method("GET".to_string()));
assert_eq!(reader.cursor.offset, 20);
assert_eq!(reader.cursor().offset, 20);
}
#[test]
@ -218,26 +218,26 @@ mod tests {
let e = entry(&mut reader).unwrap();
assert_eq!(e.request.method, Method("GET".to_string()));
assert_eq!(reader.cursor.offset, 21);
assert_eq!(reader.cursor.pos.line, 2);
assert_eq!(reader.cursor().offset, 21);
assert_eq!(reader.cursor().pos.line, 2);
let e = entry(&mut reader).unwrap();
assert_eq!(e.request.method, Method("GET".to_string()));
assert_eq!(reader.cursor.offset, 41);
assert_eq!(reader.cursor.pos.line, 2);
assert_eq!(reader.cursor().offset, 41);
assert_eq!(reader.cursor().pos.line, 2);
let mut reader =
Reader::new("GET http://google.fr # comment1\nGET http://google.fr # comment2");
let e = entry(&mut reader).unwrap();
assert_eq!(e.request.method, Method("GET".to_string()));
assert_eq!(reader.cursor.offset, 32);
assert_eq!(reader.cursor.pos.line, 2);
assert_eq!(reader.cursor().offset, 32);
assert_eq!(reader.cursor().pos.line, 2);
let e = entry(&mut reader).unwrap();
assert_eq!(e.request.method, Method("GET".to_string()));
assert_eq!(reader.cursor.offset, 63);
assert_eq!(reader.cursor.pos.line, 2);
assert_eq!(reader.cursor().offset, 63);
assert_eq!(reader.cursor().pos.line, 2);
}
#[test]
@ -287,7 +287,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 21)),
};
assert_eq!(request(&mut reader).unwrap(), default_request);
assert_eq!(reader.cursor.offset, 20);
assert_eq!(reader.cursor().offset, 20);
let mut reader = Reader::new("GET http://google.fr # comment");
let default_request = Request {
@ -329,12 +329,12 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 32)),
};
assert_eq!(request(&mut reader).unwrap(), default_request);
assert_eq!(reader.cursor.offset, 31);
assert_eq!(reader.cursor().offset, 31);
let mut reader = Reader::new("GET http://google.fr\nGET http://google.fr");
let r = request(&mut reader).unwrap();
assert_eq!(r.method, Method("GET".to_string()));
assert_eq!(reader.cursor.offset, 21);
assert_eq!(reader.cursor().offset, 21);
let r = request(&mut reader).unwrap();
assert_eq!(r.method, Method("GET".to_string()));
}
@ -463,20 +463,20 @@ mod tests {
let mut reader = Reader::new("xxx ");
let error = method(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 1 });
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
let mut reader = Reader::new("");
let error = method(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 1 });
assert_eq!(reader.cursor.offset, 0);
assert_eq!(reader.cursor().offset, 0);
let mut reader = Reader::new("GET ");
assert_eq!(method(&mut reader).unwrap(), Method("GET".to_string()));
assert_eq!(reader.cursor.offset, 3);
assert_eq!(reader.cursor().offset, 3);
let mut reader = Reader::new("CUSTOM");
assert_eq!(method(&mut reader).unwrap(), Method("CUSTOM".to_string()));
assert_eq!(reader.cursor.offset, 6);
assert_eq!(reader.cursor().offset, 6);
}
#[test]
@ -486,14 +486,14 @@ mod tests {
version(&mut reader).unwrap().value,
VersionValue::VersionAny
);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
let mut reader = Reader::new("HTTP\t200");
assert_eq!(
version(&mut reader).unwrap().value,
VersionValue::VersionAny
);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
let mut reader = Reader::new("HTTP/1.1 200");
assert_eq!(version(&mut reader).unwrap().value, VersionValue::Version11);
@ -546,7 +546,7 @@ mod tests {
],
})
);
assert_eq!(reader.cursor.offset, 8);
assert_eq!(reader.cursor().offset, 8);
let mut reader = Reader::new("{}");
let b = body(&mut reader).unwrap();
@ -558,7 +558,7 @@ mod tests {
elements: vec![],
})
);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("# comment\n {} # comment\nxxx");
let b = body(&mut reader).unwrap();
@ -570,7 +570,7 @@ mod tests {
elements: vec![],
})
);
assert_eq!(reader.cursor.offset, 24);
assert_eq!(reader.cursor().offset, 24);
let mut reader = Reader::new("{x");
let error = body(&mut reader).err().unwrap();

View File

@ -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.cursor;
let save = reader.cursor();
let no_whitespace = Whitespace {
value: String::new(),
source_info: SourceInfo {
@ -47,7 +47,7 @@ fn predicate_not(reader: &mut Reader) -> (bool, Whitespace) {
match one_or_more_spaces(reader) {
Ok(space) => (true, space),
Err(_) => {
reader.cursor = save;
reader.seek(save);
(false, no_whitespace)
}
}
@ -57,17 +57,17 @@ fn predicate_not(reader: &mut Reader) -> (bool, Whitespace) {
}
fn predicate_func(reader: &mut Reader) -> ParseResult<PredicateFunc> {
let start = reader.cursor.pos;
let start = reader.cursor();
let value = predicate_func_value(reader)?;
let end = reader.cursor.pos;
let end = reader.cursor();
Ok(PredicateFunc {
source_info: SourceInfo { start, end },
source_info: SourceInfo::new(start.pos, end.pos),
value,
})
}
fn predicate_func_value(reader: &mut Reader) -> ParseResult<PredicateFuncValue> {
let start = reader.cursor;
let start = reader.cursor();
match choice(
&[
equal_predicate,
@ -164,7 +164,7 @@ fn greater_predicate(reader: &mut Reader) -> ParseResult<PredicateFuncValue> {
} else {
one_or_more_spaces(reader)?
};
let start = reader.cursor;
let start = reader.cursor();
let value = predicate_value(reader)?;
if value.is_number() || value.is_string() || value.is_expression() {
Ok(PredicateFuncValue::GreaterThan {
@ -191,7 +191,7 @@ fn greater_or_equal_predicate(reader: &mut Reader) -> ParseResult<PredicateFuncV
} else {
one_or_more_spaces(reader)?
};
let start = reader.cursor;
let start = reader.cursor();
let value = predicate_value(reader)?;
if value.is_number() || value.is_string() || value.is_expression() {
Ok(PredicateFuncValue::GreaterThanOrEqual {
@ -218,7 +218,7 @@ fn less_predicate(reader: &mut Reader) -> ParseResult<PredicateFuncValue> {
} else {
one_or_more_spaces(reader)?
};
let start = reader.cursor;
let start = reader.cursor();
let value = predicate_value(reader)?;
if value.is_number() || value.is_string() || value.is_expression() {
Ok(PredicateFuncValue::LessThan {
@ -245,7 +245,7 @@ fn less_or_equal_predicate(reader: &mut Reader) -> ParseResult<PredicateFuncValu
} else {
one_or_more_spaces(reader)?
};
let start = reader.cursor;
let start = reader.cursor();
let value = predicate_value(reader)?;
if value.is_number() || value.is_string() || value.is_expression() {
Ok(PredicateFuncValue::LessThanOrEqual {
@ -265,7 +265,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.cursor;
let save = reader.cursor();
let value = predicate_value(reader)?;
if !value.is_string() && !value.is_bytearray() {
return Err(ParseError::new(
@ -280,7 +280,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.cursor;
let save = reader.cursor();
let value = predicate_value(reader)?;
if !value.is_string() && !value.is_bytearray() {
return Err(ParseError::new(
@ -295,7 +295,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.cursor;
let save = reader.cursor();
let value = predicate_value(reader)?;
if !value.is_string() && !value.is_bytearray() {
return Err(ParseError::new(
@ -317,7 +317,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.cursor;
let save = reader.cursor();
let value = predicate_value(reader)?;
if !matches!(value, PredicateValue::String(_)) && !matches!(value, PredicateValue::Regex(_)) {
return Err(ParseError::new(
@ -397,7 +397,7 @@ mod tests {
}
)
);
assert_eq!(reader.cursor.pos, Pos { line: 1, column: 1 });
assert_eq!(reader.cursor().pos, Pos { line: 1, column: 1 });
let mut reader = Reader::new("not XX");
assert_eq!(
@ -410,7 +410,7 @@ mod tests {
}
)
);
assert_eq!(reader.cursor.pos, Pos { line: 1, column: 5 });
assert_eq!(reader.cursor().pos, Pos { line: 1, column: 5 });
}
#[test]

View File

@ -23,14 +23,14 @@ use crate::parser::{base64, filename, key_string, ParseResult};
use crate::reader::Reader;
pub fn space(reader: &mut Reader) -> ParseResult<Whitespace> {
let start = reader.cursor;
let start = reader.cursor();
match reader.read() {
None => Err(ParseError::new(start.pos, true, ParseErrorKind::Space)),
Some(c) => {
if c == ' ' || c == '\t' {
Ok(Whitespace {
value: c.to_string(),
source_info: SourceInfo::new(start.pos, reader.cursor.pos),
source_info: SourceInfo::new(start.pos, reader.cursor().pos),
})
} else {
Err(ParseError::new(start.pos, true, ParseErrorKind::Space))
@ -40,13 +40,13 @@ pub fn space(reader: &mut Reader) -> ParseResult<Whitespace> {
}
pub fn one_or_more_spaces(reader: &mut Reader) -> ParseResult<Whitespace> {
let start = reader.cursor;
let start = reader.cursor();
match one_or_more(space, reader) {
Ok(v) => {
let s = v.iter().map(|x| x.value.clone()).collect();
Ok(Whitespace {
value: s,
source_info: SourceInfo::new(start.pos, reader.cursor.pos),
source_info: SourceInfo::new(start.pos, reader.cursor().pos),
})
}
Err(e) => Err(e),
@ -54,14 +54,14 @@ 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.cursor;
let start = reader.cursor();
match zero_or_more(space, reader) {
//Ok(v) => return Ok(v.join("")),
Ok(v) => {
let s = v.iter().map(|x| x.value.clone()).collect();
Ok(Whitespace {
value: s,
source_info: SourceInfo::new(start.pos, reader.cursor.pos),
source_info: SourceInfo::new(start.pos, reader.cursor().pos),
})
}
Err(e) => Err(e),
@ -75,7 +75,7 @@ pub fn line_terminator(reader: &mut Reader) -> ParseResult<LineTerminator> {
let nl = if reader.is_eof() {
Whitespace {
value: String::new(),
source_info: SourceInfo::new(reader.cursor.pos, reader.cursor.pos),
source_info: SourceInfo::new(reader.cursor().pos, reader.cursor().pos),
}
} else {
match newline(reader) {
@ -102,40 +102,37 @@ 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.cursor;
let start = reader.cursor();
let mut value = String::new();
loop {
if reader.is_eof() {
break;
}
let save_state = reader.cursor;
let save_state = reader.cursor();
match newline(reader) {
Ok(_) => {
reader.cursor = save_state;
reader.seek(save_state);
break;
}
_ => {
reader.cursor = save_state;
reader.seek(save_state);
if let Some(c) = reader.read() {
value.push(c);
}
}
}
}
let end = reader.cursor();
Ok(Comment {
value,
source_info: SourceInfo {
start: start.pos,
end: reader.cursor.pos,
},
source_info: SourceInfo::new(start.pos, end.pos),
})
}
/// Does not return a value, non recoverable parser. Use combinator recover to make it recoverable
pub fn literal(s: &str, reader: &mut Reader) -> ParseResult<()> {
let start = reader.cursor;
let start = reader.cursor();
for c in s.chars() {
let _state = reader.cursor;
match reader.read() {
None => {
let kind = ParseErrorKind::Expecting {
@ -160,11 +157,11 @@ pub fn literal(s: &str, reader: &mut Reader) -> ParseResult<()> {
/// Recoverable version which reset the cursor, meant to be combined with following action.
pub fn try_literal(s: &str, reader: &mut Reader) -> ParseResult<()> {
let save_state = reader.cursor;
let save_state = reader.cursor();
match literal(s, reader) {
Ok(_) => Ok(()),
Err(e) => {
reader.cursor = save_state;
reader.seek(save_state);
Err(ParseError::new(e.pos, true, e.kind))
}
}
@ -172,15 +169,15 @@ pub fn try_literal(s: &str, reader: &mut Reader) -> ParseResult<()> {
/// Returns the literal string
pub fn try_literals(s1: &str, s2: &str, reader: &mut Reader) -> ParseResult<String> {
let start = reader.cursor;
let start = reader.cursor();
match literal(s1, reader) {
Ok(_) => Ok(s1.to_string()),
Err(_) => {
reader.cursor = start;
reader.seek(start);
match literal(s2, reader) {
Ok(_) => Ok(s2.to_string()),
Err(_) => {
reader.cursor = start;
reader.seek(start);
let kind = ParseErrorKind::Expecting {
value: format!("<{s1}> or <{s2}>"),
};
@ -192,16 +189,16 @@ pub fn try_literals(s1: &str, s2: &str, reader: &mut Reader) -> ParseResult<Stri
}
pub fn newline(reader: &mut Reader) -> ParseResult<Whitespace> {
let start = reader.cursor;
let start = reader.cursor();
match try_literal("\r\n", reader) {
Ok(_) => Ok(Whitespace {
value: "\r\n".to_string(),
source_info: SourceInfo::new(start.pos, reader.cursor.pos),
source_info: SourceInfo::new(start.pos, reader.cursor().pos),
}),
Err(_) => match literal("\n", reader) {
Ok(_) => Ok(Whitespace {
value: "\n".to_string(),
source_info: SourceInfo::new(start.pos, reader.cursor.pos),
source_info: SourceInfo::new(start.pos, reader.cursor().pos),
}),
Err(_) => {
let kind = ParseErrorKind::Expecting {
@ -238,10 +235,10 @@ pub fn hex(reader: &mut Reader) -> ParseResult<Hex> {
literal(",", reader)?;
let space0 = zero_or_more_spaces(reader)?;
let mut value: Vec<u8> = vec![];
let start = reader.cursor.offset;
let start = reader.cursor();
let mut current: i32 = -1;
loop {
let s = reader.cursor;
let s = reader.cursor();
match hex_digit(reader) {
Ok(d) => {
if current != -1 {
@ -252,19 +249,19 @@ pub fn hex(reader: &mut Reader) -> ParseResult<Hex> {
}
}
Err(_) => {
reader.cursor = s;
reader.seek(s);
break;
}
};
}
if current != -1 {
return Err(ParseError::new(
reader.cursor.pos,
reader.cursor().pos,
false,
ParseErrorKind::OddNumberOfHexDigits,
));
}
let encoded = reader.peek_back(start);
let encoded = reader.peek_back(start.offset);
let space1 = zero_or_more_spaces(reader)?;
literal(";", reader)?;
@ -278,7 +275,7 @@ pub fn hex(reader: &mut Reader) -> ParseResult<Hex> {
pub fn regex(reader: &mut Reader) -> ParseResult<Regex> {
try_literal("/", reader)?;
let start = reader.cursor.pos;
let start = reader.cursor();
let mut s = String::new();
// Hurl escaping /
@ -293,7 +290,7 @@ pub fn regex(reader: &mut Reader) -> ParseResult<Regex> {
let kind = ParseErrorKind::RegexExpr {
message: "unexpected end of file".to_string(),
};
return Err(ParseError::new(reader.cursor.pos, false, kind));
return Err(ParseError::new(reader.cursor().pos, false, kind));
}
Some('/') => break,
Some('\\') => {
@ -332,7 +329,7 @@ pub fn regex(reader: &mut Reader) -> ParseResult<Regex> {
_ => "unknown".to_string(),
};
Err(ParseError::new(
start,
start.pos,
false,
ParseErrorKind::RegexExpr { message },
))
@ -345,7 +342,7 @@ pub fn null(reader: &mut Reader) -> ParseResult<()> {
}
pub fn boolean(reader: &mut Reader) -> ParseResult<bool> {
let start = reader.cursor;
let start = reader.cursor();
match try_literal("true", reader) {
Ok(_) => Ok(true),
Err(_) => match literal("false", reader) {
@ -361,7 +358,7 @@ pub fn boolean(reader: &mut Reader) -> ParseResult<bool> {
}
pub(crate) fn file(reader: &mut Reader) -> ParseResult<File> {
let _start = reader.cursor;
let _start = reader.cursor();
try_literal("file", reader)?;
literal(",", reader)?;
let space0 = zero_or_more_spaces(reader)?;
@ -378,14 +375,13 @@ 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.cursor;
try_literal("base64", reader)?;
literal(",", reader)?;
let space0 = zero_or_more_spaces(reader)?;
let save_state = reader.cursor;
let save_state = reader.cursor();
let value = base64::parse(reader);
let count = reader.cursor.offset - save_state.offset;
reader.cursor = save_state;
let count = reader.cursor().offset - save_state.offset;
reader.seek(save_state);
let encoded = reader.read_n(count);
let space1 = zero_or_more_spaces(reader)?;
literal(";", reader)?;
@ -404,7 +400,7 @@ pub fn eof(reader: &mut Reader) -> ParseResult<()> {
let kind = ParseErrorKind::Expecting {
value: String::from("eof"),
};
Err(ParseError::new(reader.cursor.pos, false, kind))
Err(ParseError::new(reader.cursor().pos, false, kind))
}
}
@ -431,7 +427,7 @@ pub fn hex_digit_value(c: char) -> Option<u32> {
}
pub fn hex_digit(reader: &mut Reader) -> ParseResult<u32> {
let start = reader.clone().cursor;
let start = reader.cursor();
match reader.read() {
Some(c) => match hex_digit_value(c) {
Some(v) => Ok(v),
@ -451,7 +447,7 @@ mod tests {
let mut reader = Reader::new("x");
let error = space(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 1 });
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
let mut reader = Reader::new(" ");
assert_eq!(
@ -461,7 +457,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 2)),
}),
);
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
}
#[test]
@ -490,7 +486,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 3)),
})
);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("xxx");
assert_eq!(
@ -500,7 +496,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 1)),
})
);
assert_eq!(reader.cursor.offset, 0);
assert_eq!(reader.cursor().offset, 0);
let mut reader = Reader::new(" xxx");
assert_eq!(
@ -510,7 +506,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 2)),
})
);
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
}
#[test]
@ -541,7 +537,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 2), Pos::new(1, 10)),
})
);
assert_eq!(reader.cursor.offset, 9);
assert_eq!(reader.cursor().offset, 9);
let mut reader = Reader::new("xxx");
let error = comment(&mut reader).err().unwrap();
@ -553,7 +549,7 @@ mod tests {
fn test_literal() {
let mut reader = Reader::new("hello");
assert_eq!(literal("hello", &mut reader), Ok(()));
assert_eq!(reader.cursor.offset, 5);
assert_eq!(reader.cursor().offset, 5);
let mut reader = Reader::new("");
let error = literal("hello", &mut reader).err().unwrap();
@ -564,7 +560,7 @@ mod tests {
value: String::from("hello")
}
);
assert_eq!(reader.cursor.offset, 0);
assert_eq!(reader.cursor().offset, 0);
let mut reader = Reader::new("hi");
let error = literal("hello", &mut reader).err().unwrap();
@ -575,7 +571,7 @@ mod tests {
value: String::from("hello")
}
);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("he");
let error = literal("hello", &mut reader).err().unwrap();
@ -586,7 +582,7 @@ mod tests {
value: String::from("hello")
}
);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
}
#[test]
@ -732,7 +728,7 @@ mod tests {
},
}
);
assert_eq!(reader.cursor.offset, 14);
assert_eq!(reader.cursor().offset, 14);
}
#[test]
@ -741,13 +737,13 @@ mod tests {
let error = key_value(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 6 });
assert!(error.recoverable);
assert_eq!(reader.cursor.offset, 5); // does not reset cursor
assert_eq!(reader.cursor().offset, 5); // does not reset cursor
let mut reader = Reader::new("GET http://google.fr");
let error = key_value(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 5 });
assert!(error.recoverable);
assert_eq!(reader.cursor.offset, 5); // does not reset cursor
assert_eq!(reader.cursor().offset, 5); // does not reset cursor
}
#[test]
@ -1053,6 +1049,6 @@ mod tests {
},
}
);
assert_eq!(reader.cursor.offset, 15);
assert_eq!(reader.cursor().offset, 15);
}
}

View File

@ -24,11 +24,11 @@ use crate::parser::{ParseError, ParseErrorKind, ParseResult};
use crate::reader::{Pos, Reader};
pub fn query(reader: &mut Reader) -> ParseResult<Query> {
let start = reader.cursor.pos;
let start = reader.cursor();
let value = query_value(reader)?;
let end = reader.cursor.pos;
let end = reader.cursor();
Ok(Query {
source_info: SourceInfo { start, end },
source_info: SourceInfo::new(start.pos, end.pos),
value,
})
}
@ -77,13 +77,13 @@ fn cookie_query(reader: &mut Reader) -> ParseResult<QueryValue> {
let space0 = one_or_more_spaces(reader)?;
// Read the whole value of the coookie path and parse it with a specialized reader.
let start = reader.cursor.pos;
let start = reader.cursor();
let s = quoted_oneline_string(reader)?;
// todo should work with an encodedString in order to support escape sequence
// or decode escape sequence with the cookiepath parser
// We will parse the cookiepath value without `"`.
let pos = Pos::new(start.line, start.column + 1);
let pos = Pos::new(start.pos.line, start.pos.column + 1);
let mut cookiepath_reader = Reader::with_pos(s.as_str(), pos);
let expr = cookiepath(&mut cookiepath_reader)?;
@ -205,8 +205,8 @@ fn certificate_field(reader: &mut Reader) -> ParseResult<CertificateAttributeNam
let value =
"Field <Subject>, <Issuer>, <Start-Date>, <Expire-Date> or <Serial-Number>".to_string();
let kind = ParseErrorKind::Expecting { value };
let pos = reader.cursor.pos;
Err(ParseError::new(pos, false, kind))
let cur = reader.cursor();
Err(ParseError::new(cur.pos, false, kind))
}
}
@ -295,7 +295,7 @@ mod tests {
},
}
);
assert_eq!(reader.cursor.offset, 20);
assert_eq!(reader.cursor().offset, 20);
// todo test with escape sequence
//let mut reader = Reader::init("cookie \"cookie\u{31}\"");
@ -402,6 +402,6 @@ mod tests {
}
)]
);
assert_eq!(reader.cursor.offset, 14);
assert_eq!(reader.cursor().offset, 14);
}
}

View File

@ -39,12 +39,10 @@ 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.cursor.pos;
let start = reader.cursor();
let name = section_name(reader)?;
let source_info = SourceInfo {
start,
end: reader.cursor.pos,
};
let source_info = SourceInfo::new(start.pos, reader.cursor().pos);
let line_terminator0 = line_terminator(reader)?;
let value = match name.as_str() {
"QueryStringParams" => section_value_query_params(reader)?,
@ -55,7 +53,7 @@ fn request_section(reader: &mut Reader) -> ParseResult<Section> {
"Options" => section_value_options(reader)?,
_ => {
let kind = ParseErrorKind::RequestSectionName { name: name.clone() };
let pos = Pos::new(start.line, start.column + 1);
let pos = Pos::new(start.pos.line, start.pos.column + 1);
return Err(ParseError::new(pos, false, kind));
}
};
@ -72,19 +70,18 @@ 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.cursor.pos;
let start = reader.cursor();
let name = section_name(reader)?;
let source_info = SourceInfo {
start,
end: reader.cursor.pos,
};
let end = reader.cursor();
let source_info = SourceInfo::new(start.pos, end.pos);
let line_terminator0 = line_terminator(reader)?;
let value = match name.as_str() {
"Captures" => section_value_captures(reader)?,
"Asserts" => section_value_asserts(reader)?,
_ => {
let kind = ParseErrorKind::ResponseSectionName { name: name.clone() };
let pos = Pos::new(start.line, start.column + 1);
let pos = Pos::new(start.pos.line, start.pos.column + 1);
return Err(ParseError::new(pos, false, kind));
}
};
@ -99,7 +96,7 @@ fn response_section(reader: &mut Reader) -> ParseResult<Section> {
}
fn section_name(reader: &mut Reader) -> ParseResult<String> {
let pos = reader.cursor.pos;
let pos = reader.cursor().pos;
try_literal("[", reader)?;
let name = reader.read_while(|c| c.is_alphanumeric());
if name.is_empty() {
@ -175,12 +172,12 @@ fn cookie(reader: &mut Reader) -> ParseResult<Cookie> {
}
fn multipart_param(reader: &mut Reader) -> ParseResult<MultipartParam> {
let save = reader.cursor;
let save = reader.cursor();
match file_param(reader) {
Ok(f) => Ok(MultipartParam::FileParam(f)),
Err(e) => {
if e.recoverable {
reader.cursor = save;
reader.seek(save);
let param = key_value(reader)?;
Ok(MultipartParam::Param(param))
} else {
@ -216,10 +213,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.cursor;
let save = reader.cursor();
let (space2, content_type) = match line_terminator(reader) {
Ok(_) => {
reader.cursor = save;
reader.seek(save);
let space2 = Whitespace {
value: String::new(),
source_info: SourceInfo {
@ -230,7 +227,7 @@ fn file_value(reader: &mut Reader) -> ParseResult<FileValue> {
(space2, None)
}
Err(_) => {
reader.cursor = save;
reader.seek(save);
let space2 = zero_or_more_spaces(reader)?;
let content_type = file_content_type(reader)?;
(space2, Some(content_type))
@ -247,16 +244,16 @@ fn file_value(reader: &mut Reader) -> ParseResult<FileValue> {
}
fn file_content_type(reader: &mut Reader) -> ParseResult<String> {
let start = reader.cursor;
let start = reader.cursor();
let mut buf = String::new();
let mut spaces = String::new();
let mut save = reader.cursor;
let mut save = reader.cursor();
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.cursor;
save = reader.cursor();
} else if c == ' ' {
spaces.push(' ');
} else {
@ -264,7 +261,7 @@ fn file_content_type(reader: &mut Reader) -> ParseResult<String> {
}
}
reader.cursor = save;
reader.seek(save);
if buf.is_empty() {
return Err(ParseError::new(
start.pos,
@ -551,21 +548,21 @@ mod tests {
file_content_type(&mut reader).unwrap(),
"text/html".to_string()
);
assert_eq!(reader.cursor.offset, 9);
assert_eq!(reader.cursor().offset, 9);
let mut reader = Reader::new("text/plain; charset=us-ascii");
assert_eq!(
file_content_type(&mut reader).unwrap(),
"text/plain; charset=us-ascii".to_string()
);
assert_eq!(reader.cursor.offset, 28);
assert_eq!(reader.cursor().offset, 28);
let mut reader = Reader::new("text/html # comment");
assert_eq!(
file_content_type(&mut reader).unwrap(),
"text/html".to_string()
);
assert_eq!(reader.cursor.offset, 9);
assert_eq!(reader.cursor().offset, 9);
}
#[test]
@ -631,7 +628,7 @@ mod tests {
},
}
);
assert_eq!(reader.cursor.offset, 43);
assert_eq!(reader.cursor().offset, 43);
}
#[test]
@ -793,7 +790,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 12)),
}
);
assert_eq!(reader.cursor.pos, Pos { line: 3, column: 1 });
assert_eq!(reader.cursor().pos, Pos { line: 3, column: 1 });
let mut reader = Reader::new("[BasicAuth]\nHTTP 200\n");
assert_eq!(
@ -819,6 +816,6 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 12)),
}
);
assert_eq!(reader.cursor.pos, Pos { line: 2, column: 1 });
assert_eq!(reader.cursor().pos, Pos { line: 2, column: 1 });
}
}

View File

@ -27,12 +27,12 @@ use crate::reader::Reader;
/// the string does not contain trailing space
/// 2- templatize
pub fn unquoted_template(reader: &mut Reader) -> ParseResult<Template> {
let start = reader.cursor;
let start = reader.cursor();
let mut chars = vec![];
let mut spaces = vec![];
let mut end = start;
loop {
let pos = reader.cursor.pos;
let pos = reader.cursor().pos;
match any_char(vec!['#'], reader) {
Err(e) => {
if e.recoverable {
@ -53,27 +53,21 @@ pub fn unquoted_template(reader: &mut Reader) -> ParseResult<Template> {
spaces = vec![];
}
chars.push((c, s, pos));
end = reader.cursor;
end = reader.cursor();
}
}
}
}
reader.cursor = end;
reader.seek(end);
let encoded_string = template::EncodedString {
source_info: SourceInfo {
start: start.pos,
end: end.pos,
},
source_info: SourceInfo::new(start.pos, end.pos),
chars,
};
let elements = template::templatize(encoded_string)?;
Ok(Template {
delimiter: None,
elements,
source_info: SourceInfo {
start: start.pos,
end: end.pos,
},
source_info: SourceInfo::new(start.pos, end.pos),
})
}
@ -87,17 +81,17 @@ pub fn quoted_oneline_string(reader: &mut Reader) -> ParseResult<String> {
}
pub fn quoted_template(reader: &mut Reader) -> ParseResult<Template> {
let start = reader.cursor.pos;
let start = reader.cursor();
let mut end = start;
try_literal("\"", reader)?;
let mut chars = vec![];
loop {
let pos = reader.cursor.pos;
let save = reader.cursor;
let pos = reader.cursor().pos;
let save = reader.cursor();
match any_char(vec!['"'], reader) {
Err(e) => {
if e.recoverable {
reader.cursor = save;
reader.seek(save);
break;
} else {
return Err(e);
@ -105,39 +99,36 @@ pub fn quoted_template(reader: &mut Reader) -> ParseResult<Template> {
}
Ok((c, s)) => {
chars.push((c, s, pos));
end = reader.cursor.pos;
end = reader.cursor();
}
}
}
literal("\"", reader)?;
let encoded_string = template::EncodedString {
source_info: SourceInfo { start, end },
source_info: SourceInfo::new(start.pos, end.pos),
chars,
};
let elements = template::templatize(encoded_string)?;
Ok(Template {
delimiter: Some('"'),
elements,
source_info: SourceInfo {
start,
end: reader.cursor.pos,
},
source_info: SourceInfo::new(start.pos, reader.cursor().pos),
})
}
pub fn backtick_template(reader: &mut Reader) -> ParseResult<Template> {
let delimiter = Some('`');
let start = reader.cursor.pos;
let start = reader.cursor();
let mut end = start;
try_literal("`", reader)?;
let mut chars = vec![];
loop {
let pos = reader.cursor.pos;
let save = reader.cursor;
let pos = reader.cursor().pos;
let save = reader.cursor();
match any_char(vec!['`', '\n'], reader) {
Err(e) => {
if e.recoverable {
reader.cursor = save;
reader.seek(save);
break;
} else {
return Err(e);
@ -145,33 +136,30 @@ pub fn backtick_template(reader: &mut Reader) -> ParseResult<Template> {
}
Ok((c, s)) => {
chars.push((c, s, pos));
end = reader.cursor.pos;
end = reader.cursor();
}
}
}
literal("`", reader)?;
let encoded_string = template::EncodedString {
source_info: SourceInfo { start, end },
source_info: SourceInfo::new(start.pos, end.pos),
chars,
};
let elements = template::templatize(encoded_string)?;
Ok(Template {
delimiter,
elements,
source_info: SourceInfo {
start,
end: reader.cursor.pos,
},
source_info: SourceInfo::new(start.pos, reader.cursor().pos),
})
}
fn any_char(except: Vec<char>, reader: &mut Reader) -> ParseResult<(char, String)> {
let start = reader.cursor;
let start = reader.cursor();
match escape_char(reader) {
Ok(c) => Ok((c, reader.peek_back(start.offset))),
Err(e) => {
if e.recoverable {
reader.cursor = start;
reader.seek(start);
match reader.read() {
None => {
let kind = ParseErrorKind::Expecting {
@ -201,7 +189,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.cursor;
let start = reader.cursor();
match reader.read() {
Some('#') => Ok('#'),
Some('"') => Ok('"'),
@ -228,7 +216,7 @@ pub(crate) fn unicode(reader: &mut Reader) -> ParseResult<char> {
let c = match std::char::from_u32(v) {
None => {
return Err(ParseError::new(
reader.cursor.pos,
reader.cursor().pos,
false,
ParseErrorKind::Unicode,
))
@ -269,7 +257,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 1)),
}
);
assert_eq!(reader.cursor.offset, 0);
assert_eq!(reader.cursor().offset, 0);
}
#[test]
@ -286,7 +274,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 2)),
}
);
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
}
#[test]
@ -303,7 +291,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 8)),
}
);
assert_eq!(reader.cursor.offset, 7);
assert_eq!(reader.cursor().offset, 7);
}
#[test]
@ -320,7 +308,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 5)),
}
);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
}
#[test]
@ -357,7 +345,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 21)),
}
);
assert_eq!(reader.cursor.offset, 20);
assert_eq!(reader.cursor().offset, 20);
}
#[test]
@ -371,7 +359,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 3)),
}
);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("\"a#\"");
assert_eq!(
@ -385,7 +373,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 5)),
}
);
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
let mut reader = Reader::new("\"{0}\"");
assert_eq!(
@ -399,7 +387,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 6)),
}
);
assert_eq!(reader.cursor.offset, 5);
assert_eq!(reader.cursor().offset, 5);
}
#[test]
@ -417,7 +405,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 9)),
}
);
assert_eq!(reader.cursor.offset, 8);
assert_eq!(reader.cursor().offset, 8);
}
#[test]
@ -438,11 +426,11 @@ mod tests {
fn test_quoted_string() {
let mut reader = Reader::new("\"\"");
assert_eq!(quoted_oneline_string(&mut reader).unwrap(), "");
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("\"Hello\"");
assert_eq!(quoted_oneline_string(&mut reader).unwrap(), "Hello");
assert_eq!(reader.cursor.offset, 7);
assert_eq!(reader.cursor().offset, 7);
}
#[test]
@ -456,7 +444,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 3)),
}
);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("`foo#`");
assert_eq!(
@ -470,7 +458,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 7)),
}
);
assert_eq!(reader.cursor.offset, 6);
assert_eq!(reader.cursor().offset, 6);
let mut reader = Reader::new("`{0}`");
assert_eq!(
@ -484,7 +472,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 6)),
}
);
assert_eq!(reader.cursor.offset, 5);
assert_eq!(reader.cursor().offset, 5);
}
#[test]
@ -502,7 +490,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 9)),
}
);
assert_eq!(reader.cursor.offset, 8);
assert_eq!(reader.cursor().offset, 8);
}
#[test]
@ -526,28 +514,28 @@ mod tests {
any_char(vec![], &mut reader).unwrap(),
('a', "a".to_string())
);
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
let mut reader = Reader::new(" ");
assert_eq!(
any_char(vec![], &mut reader).unwrap(),
(' ', " ".to_string())
);
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
let mut reader = Reader::new("\\t");
assert_eq!(
any_char(vec![], &mut reader).unwrap(),
('\t', "\\t".to_string())
);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("#");
assert_eq!(
any_char(vec![], &mut reader).unwrap(),
('#', "#".to_string())
);
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
}
#[test]
@ -557,7 +545,7 @@ mod tests {
any_char(vec![], &mut reader).unwrap(),
('"', "\\\"".to_string())
);
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
}
#[test]
@ -582,11 +570,11 @@ mod tests {
fn test_escape_char() {
let mut reader = Reader::new("\\n");
assert_eq!(escape_char(&mut reader).unwrap(), '\n');
assert_eq!(reader.cursor.offset, 2);
assert_eq!(reader.cursor().offset, 2);
let mut reader = Reader::new("\\u{0a}");
assert_eq!(escape_char(&mut reader).unwrap(), '\n');
assert_eq!(reader.cursor.offset, 6);
assert_eq!(reader.cursor().offset, 6);
let mut reader = Reader::new("x");
let error = escape_char(&mut reader).err().unwrap();
@ -598,18 +586,18 @@ mod tests {
}
);
assert!(error.recoverable);
assert_eq!(reader.cursor.offset, 0);
assert_eq!(reader.cursor().offset, 0);
}
#[test]
fn test_unicode() {
let mut reader = Reader::new("{000a}");
assert_eq!(unicode(&mut reader).unwrap(), '\n');
assert_eq!(reader.cursor.offset, 6);
assert_eq!(reader.cursor().offset, 6);
let mut reader = Reader::new("{E9}");
assert_eq!(unicode(&mut reader).unwrap(), 'é');
assert_eq!(reader.cursor.offset, 4);
assert_eq!(reader.cursor().offset, 4);
}
#[test]
@ -638,7 +626,7 @@ mod tests {
let now = SystemTime::now();
assert!(quoted_template(&mut reader).is_ok());
assert_eq!(reader.cursor.offset, 14);
assert_eq!(reader.cursor().offset, 14);
eprintln!("duration= {}", now.elapsed().unwrap().as_nanos());
}
}

View File

@ -18,7 +18,7 @@
use crate::ast::{Expr, SourceInfo, TemplateElement};
use crate::parser::primitives::{literal, try_literal};
use crate::parser::{error, expr, ParseResult};
use crate::reader::{Cursor, Pos, Reader};
use crate::reader::{Pos, Reader};
pub struct EncodedString {
pub source_info: SourceInfo,
@ -90,11 +90,7 @@ pub fn templatize(encoded_string: EncodedString) -> ParseResult<Vec<TemplateElem
State::FirstCloseBracket => {
if s.as_str() == "}" {
let mut reader = Reader::new(encoded.as_str());
reader.cursor = Cursor {
offset: 0,
pos: expression_start.unwrap(),
};
let mut reader = Reader::with_pos(encoded.as_str(), expression_start.unwrap());
let expression = expr::parse2(&mut reader)?;
elements.push(TemplateElement::Expression(expression));
value = String::new();

View File

@ -24,26 +24,26 @@ use crate::reader::Reader;
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.cursor;
let start = reader.cursor();
let mut elements = vec![];
let mut buffer = String::new();
if !url_prefix_valid(reader) {
return Err(ParseError::new(
reader.cursor.pos,
reader.cursor().pos,
false,
ParseErrorKind::UrlInvalidStart,
));
}
loop {
let save = reader.cursor;
let save = reader.cursor();
match line_terminator(reader) {
Ok(_) => {
reader.cursor = save;
reader.seek(save);
break;
}
_ => reader.cursor = save,
_ => reader.seek(save),
}
match expr::parse(reader) {
@ -61,7 +61,7 @@ pub fn url(reader: &mut Reader) -> ParseResult<Template> {
if !e.recoverable {
return Err(e);
} else {
reader.cursor = save;
reader.seek(save);
match reader.read() {
None => break,
Some(c) => {
@ -74,7 +74,7 @@ pub fn url(reader: &mut Reader) -> ParseResult<Template> {
{
buffer.push(c);
} else {
reader.cursor = save;
reader.seek(save);
break;
}
}
@ -92,25 +92,22 @@ pub fn url(reader: &mut Reader) -> ParseResult<Template> {
}
// URLs should be followed by a line terminator
let save = reader.cursor;
let save = reader.cursor();
if line_terminator(reader).is_err() {
reader.cursor = save;
reader.seek(save);
let c = reader.peek().unwrap();
return Err(ParseError::new(
reader.cursor.pos,
reader.cursor().pos,
false,
ParseErrorKind::UrlIllegalCharacter(c),
));
}
reader.cursor = save;
reader.seek(save);
Ok(Template {
delimiter: None,
elements,
source_info: SourceInfo {
start: start.pos,
end: reader.cursor.pos,
},
source_info: SourceInfo::new(start.pos, reader.cursor().pos),
})
}
@ -145,7 +142,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 17)),
}
);
assert_eq!(reader.cursor.offset, 16);
assert_eq!(reader.cursor().offset, 16);
}
#[test]
@ -164,7 +161,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 57)),
}
);
assert_eq!(reader.cursor.offset, 56);
assert_eq!(reader.cursor().offset, 56);
}
#[test]
@ -201,7 +198,7 @@ mod tests {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 19)),
}
);
assert_eq!(reader.cursor.offset, 18);
assert_eq!(reader.cursor().offset, 18);
}
#[test]
@ -222,7 +219,7 @@ mod tests {
}
);
assert!(!error.recoverable);
assert_eq!(reader.cursor.offset, 14);
assert_eq!(reader.cursor().offset, 14);
}
#[test]

View File

@ -56,7 +56,7 @@ pub fn parse(reader: &mut Reader) -> ParseResult<String> {
Some('<') => {}
_ => {
return Err(ParseError::new(
reader.cursor.pos,
reader.cursor().pos,
true,
ParseErrorKind::Xml,
))
@ -80,8 +80,8 @@ pub fn parse(reader: &mut Reader) -> ParseResult<String> {
ptr::null(),
);
// We keep track of the previous char reader position, to accurately raise eventual error.
let mut prev_pos = reader.cursor.pos;
// We keep track of the previous char reader position, to accurately raise eventual error.
let mut prev_pos = reader.cursor().pos;
while let Some(c) = reader.read() {
buf.push(c);
@ -107,7 +107,7 @@ pub fn parse(reader: &mut Reader) -> ParseResult<String> {
{
break;
}
prev_pos = reader.cursor.pos;
prev_pos = reader.cursor().pos;
}
xmlFreeParserCtxt(context);
@ -272,14 +272,14 @@ mod tests {
parse(&mut reader).unwrap(),
String::from("<users><user /></users>")
);
assert_eq!(reader.cursor.offset, 23);
assert_eq!(reader.cursor().offset, 23);
let mut reader = Reader::new("<users><user /></users>xx");
assert_eq!(
parse(&mut reader).unwrap(),
String::from("<users><user /></users>")
);
assert_eq!(reader.cursor.offset, 23);
assert_eq!(reader.cursor().offset, 23);
assert_eq!(reader.peek_n(2), String::from("xx"));
let mut reader = Reader::new("<?xml version=\"1.0\"?><users/>xxx");
@ -287,7 +287,7 @@ mod tests {
parse(&mut reader).unwrap(),
String::from("<?xml version=\"1.0\"?><users/>")
);
assert_eq!(reader.cursor.offset, 29);
assert_eq!(reader.cursor().offset, 29);
}
#[test]
@ -306,25 +306,25 @@ mod tests {
let output = xml;
let mut reader = Reader::new(input);
assert_eq!(parse(&mut reader).unwrap(), String::from(output),);
assert_eq!(reader.cursor.offset, 520);
assert_eq!(reader.cursor().offset, 520);
// A XML with data padding
let input = format!("{xml} xx xx xx xx");
let output = xml;
let mut reader = Reader::new(&input);
assert_eq!(parse(&mut reader).unwrap(), String::from(output),);
assert_eq!(reader.cursor.offset, 520);
assert_eq!(reader.cursor().offset, 520);
// Two consecutive XML
let input = format!("{xml}{xml}");
let output = xml;
let mut reader = Reader::new(&input);
assert_eq!(parse(&mut reader).unwrap(), String::from(output),);
assert_eq!(reader.cursor.offset, 520);
assert_eq!(reader.cursor().offset, 520);
let mut reader = Reader::new(&input);
assert_eq!(parse(&mut reader).unwrap(), String::from(output),);
assert_eq!(reader.cursor.offset, 520);
assert_eq!(reader.cursor().offset, 520);
}
#[test]
@ -453,6 +453,6 @@ mod tests {
let chunk = format!("{xml}\nHTTP 200");
let mut reader = Reader::new(&chunk);
assert_eq!(parse(&mut reader).unwrap(), String::from(xml),);
assert_eq!(reader.cursor.offset, 4411);
assert_eq!(reader.cursor().offset, 4411);
}
}

View File

@ -15,43 +15,43 @@
* limitations under the License.
*
*/
use std::cmp::min;
//! Represents a text reader.
/// Represents a text reader.
///
/// The `Reader` implements methods to read a stream of text. A reader manages
/// an internal `cursor`: the position of the current read index within the reader's buffer.
/// Methods like [`Reader::read`], [`Reader::read_while`]
/// do advance the internal reader's `cursor`. Other methods, like [`Reader::peek`], [`Reader::peek_n`]
/// allows to get the next chars in the buffer without modifying the current reader cursor.
/// an internal `cursor` : it's the current read index position within the reader's internal buffer.
///
/// Methods like [`Reader::read`], [`Reader::read_while`] do advance the internal reader's `cursor`.
/// Other methods, like [`Reader::peek`], [`Reader::peek_n`] allows to get the next chars in the
/// buffer without modifying the current reader cursor.
///
/// The cursor is composed of an offset, which is always related to the reader internal buffer.
/// Along the buffer offset, a position `[Pos]` is updated each time a char is read. This position
/// is the column and row index in the buffer document. In most of the case, the position is
/// initialize to the first char, but a reader instance can be create using `[Reader::with_pos]`
/// which set a given started position. This can be useful when a reader is instantiated as a
/// "sub reader" of a given reader, and we want to reported position relatively to the main reader
/// (for errors but also for constructed structures).
/// Along the buffer offset, a position [`Pos`] is updated each time a char is read. This position
/// corresponds to the column and row index in the buffer document. In most of the case, the
/// position is initialized to the first char, but a reader instance can be created using
/// [`Reader::with_pos`] to set a given started position. This can be useful when a reader
/// is instantiated as a "sub reader" of a given reader, and we want to report position relatively
/// to the main reader (for errors but also for constructed structures).
///
/// # Example
/// ```
/// use hurl_core::reader::Reader;
///
/// let mut reader = Reader::new("hi");
/// let state = reader.cursor.offset; // cursor is 0
/// let eof = reader.is_eof();
/// let val = reader.peek_n(2); // val = "hi"
/// let val = reader.read().unwrap(); // val = 'h'
/// assert_eq!(reader.cursor().offset, 0);
/// assert!(!reader.is_eof());
/// assert_eq!(reader.peek_n(2), "hi".to_string());
/// assert_eq!(reader.read(), Some('h'));
/// assert_eq!(reader.cursor().offset, 1);
/// ```
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Reader {
pub buffer: Vec<char>,
pub cursor: Cursor,
buffer: Vec<char>,
cursor: Cursor,
}
/// Represents a line and column position in a reader.
///
/// Index are 1-based.
/// Indices are 1-based.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Pos {
pub line: usize,
@ -65,6 +65,12 @@ impl Pos {
}
}
/// A position in a text buffer.
///
/// The position has two components: a char `offset` in the internal buffer of the reader, and
/// a column-row oriented position `pos`, used for human display. `pos` is usually initialized to
/// the first char of the buffer but it can also be set with a position inside another reader. This
/// allows the report of error of a sub-reader, relative to a parent reader.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Cursor {
pub offset: usize,
@ -73,7 +79,7 @@ pub struct Cursor {
impl Reader {
/// Creates a new reader, position of the index is at the first char.
pub fn new(s: &str) -> Reader {
pub fn new(s: &str) -> Self {
Reader {
buffer: s.chars().collect(),
cursor: Cursor {
@ -87,13 +93,23 @@ impl Reader {
/// structures and error to be referenced from this position.
///
/// Note: the `buffer` offset is still initialized to 0.
pub fn with_pos(s: &str, pos: Pos) -> Reader {
pub fn with_pos(s: &str, pos: Pos) -> Self {
Reader {
buffer: s.chars().collect(),
cursor: Cursor { offset: 0, pos },
}
}
/// Returns the current position of the read index.
pub fn cursor(&self) -> Cursor {
self.cursor
}
/// Position the read index to a new position.
pub fn seek(&mut self, to: Cursor) {
self.cursor = to;
}
/// Returns true if the reader has read all the buffer, false otherwise.
pub fn is_eof(&self) -> bool {
self.cursor.offset == self.buffer.len()
@ -171,7 +187,7 @@ impl Reader {
/// This methods can return less than `count` chars if there is not enough chars in the buffer.
pub fn peek_n(&self, count: usize) -> String {
let start = self.cursor.offset;
let end = min(start + count, self.buffer.len());
let end = (start + count).min(self.buffer.len());
self.buffer[start..end].iter().collect()
}
@ -194,15 +210,15 @@ mod tests {
#[test]
fn basic_reader() {
let mut reader = Reader::new("hi");
assert_eq!(reader.cursor.offset, 0);
assert_eq!(reader.cursor().offset, 0);
assert!(!reader.is_eof());
assert_eq!(reader.peek_n(2), "hi".to_string());
assert_eq!(reader.cursor.offset, 0);
assert_eq!(reader.cursor().offset, 0);
assert_eq!(reader.read().unwrap(), 'h');
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
assert_eq!(reader.peek().unwrap(), 'i');
assert_eq!(reader.cursor.offset, 1);
assert_eq!(reader.cursor().offset, 1);
assert_eq!(reader.read().unwrap(), 'i');
assert!(reader.is_eof());
assert_eq!(reader.read(), None);
@ -224,17 +240,17 @@ mod tests {
fn read_while() {
let mut reader = Reader::new("123456789");
assert_eq!(reader.read_while(|c| c.is_numeric()), "123456789");
assert_eq!(reader.cursor.offset, 9);
assert_eq!(reader.cursor().offset, 9);
assert!(reader.is_eof());
let mut reader = Reader::new("123456789abcde");
assert_eq!(reader.read_while(|c| c.is_numeric()), "123456789");
assert_eq!(reader.cursor.offset, 9);
assert_eq!(reader.cursor().offset, 9);
assert!(!reader.is_eof());
let mut reader = Reader::new("abcde123456789");
assert_eq!(reader.read_while(|c| c.is_numeric()), "");
assert_eq!(reader.cursor.offset, 0);
assert_eq!(reader.cursor().offset, 0);
}
#[test]
@ -244,7 +260,7 @@ mod tests {
_ = main_reader.read();
_ = main_reader.read();
let pos = main_reader.cursor.pos;
let pos = main_reader.cursor().pos;
let s = main_reader.read_while(|_| true);
let mut sub_reader = Reader::with_pos(&s, pos);
assert_eq!(