mirror of
https://github.com/Orange-OpenSource/hurl.git
synced 2024-11-26 11:43:08 +03:00
Make Reader fields private.
This commit is contained in:
parent
e7a6544494
commit
76b45a1ed1
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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]
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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]
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 })
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
@ -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]
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 });
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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]
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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!(
|
||||
|
Loading…
Reference in New Issue
Block a user