mirror of
https://github.com/Orange-OpenSource/hurl.git
synced 2024-11-11 02:40:26 +03:00
Fix performance issue in Reader reamaining method.
This commit is contained in:
parent
aa6d228487
commit
28292ef114
@ -58,7 +58,7 @@ fn string_template(reader: &mut Reader) -> ParseResult<'static, Template> {
|
||||
let mut chars = vec![];
|
||||
let start = reader.state.pos.clone();
|
||||
loop {
|
||||
if reader.remaining().starts_with('"') || reader.is_eof() {
|
||||
if reader.peek() == Some('"') || reader.is_eof() {
|
||||
break;
|
||||
}
|
||||
let char = any_char(reader)?;
|
||||
@ -209,7 +209,7 @@ pub fn number_value(reader: &mut Reader) -> ParseResult<'static, JsonValue> {
|
||||
Err(_) => "".to_string(),
|
||||
};
|
||||
|
||||
let exponent = if reader.remaining().starts_with('e') || reader.remaining().starts_with('E') {
|
||||
let exponent = if reader.peek() == Some('e') || reader.peek() == Some('E') {
|
||||
reader.read();
|
||||
let exponent_sign = match try_literal("-", reader) {
|
||||
Ok(_) => "-".to_string(),
|
||||
@ -240,15 +240,15 @@ fn list_value(reader: &mut Reader) -> ParseResult<'static, JsonValue> {
|
||||
let mut elements = vec![];
|
||||
|
||||
// at least one element
|
||||
if !reader.remaining().starts_with(']') {
|
||||
if reader.peek() != Some(']') {
|
||||
let first_element = list_element(reader)?;
|
||||
elements.push(first_element);
|
||||
|
||||
loop {
|
||||
if reader.remaining().starts_with(']') {
|
||||
if reader.peek() == Some(']') {
|
||||
break;
|
||||
}
|
||||
if !reader.remaining().starts_with(',') {
|
||||
if reader.peek() != Some(',') {
|
||||
break;
|
||||
}
|
||||
literal(",", reader)?;
|
||||
@ -286,15 +286,15 @@ pub fn object_value(reader: &mut Reader) -> ParseResult<'static, JsonValue> {
|
||||
try_literal("{", reader)?;
|
||||
let space0 = whitespace(reader);
|
||||
let mut elements = vec![];
|
||||
if !reader.remaining().starts_with('}') {
|
||||
if reader.peek() != Some('}') {
|
||||
let first_element = object_element(reader)?;
|
||||
elements.push(first_element);
|
||||
|
||||
loop {
|
||||
if reader.remaining().starts_with('}') {
|
||||
if reader.peek() == Some('}') {
|
||||
break;
|
||||
}
|
||||
if !reader.remaining().starts_with(',') {
|
||||
if reader.peek() != Some(',') {
|
||||
break;
|
||||
}
|
||||
literal(",", reader)?;
|
||||
|
@ -83,7 +83,7 @@ fn graphql(reader: &mut Reader) -> ParseResult<'static, MultilineString> {
|
||||
let mut chars = vec![];
|
||||
|
||||
let start = reader.state.pos.clone();
|
||||
while !reader.remaining().starts_with("```") && !reader.is_eof() {
|
||||
while reader.peek_n(3) != "```" && !reader.is_eof() {
|
||||
let pos = reader.state.pos.clone();
|
||||
let c = reader.read().unwrap();
|
||||
chars.push((c, c.to_string(), pos));
|
||||
@ -233,7 +233,7 @@ fn multiline_string_value(reader: &mut Reader) -> ParseResult<'static, Template>
|
||||
let mut chars = vec![];
|
||||
|
||||
let start = reader.state.pos.clone();
|
||||
while !reader.remaining().starts_with("```") && !reader.is_eof() {
|
||||
while reader.peek_n(3) != "```" && !reader.is_eof() {
|
||||
let pos = reader.state.pos.clone();
|
||||
let c = reader.read().unwrap();
|
||||
chars.push((c, c.to_string(), pos));
|
||||
@ -262,7 +262,7 @@ fn oneline_string_value(reader: &mut Reader) -> ParseResult<'static, Template> {
|
||||
let mut chars = vec![];
|
||||
|
||||
let start = reader.state.pos.clone();
|
||||
while !reader.remaining().starts_with("```") && !reader.is_eof() {
|
||||
while reader.peek_n(3) != "```" && !reader.is_eof() {
|
||||
let pos = reader.state.pos.clone();
|
||||
let c = reader.read().unwrap();
|
||||
if c == '\n' {
|
||||
|
@ -15,6 +15,8 @@
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
use std::cmp::min;
|
||||
|
||||
use crate::ast::Pos;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
@ -30,6 +32,7 @@ pub struct ReaderState {
|
||||
}
|
||||
|
||||
impl Reader {
|
||||
// FIXME: change name to the more idiomatic new
|
||||
pub fn init(s: &str) -> Reader {
|
||||
Reader {
|
||||
buffer: s.chars().collect(),
|
||||
@ -65,6 +68,12 @@ impl Reader {
|
||||
self.buffer.get(self.state.cursor).copied()
|
||||
}
|
||||
|
||||
pub fn peek_n(&self, n: usize) -> String {
|
||||
let start = self.state.cursor;
|
||||
let end = min(start + n, self.buffer.len());
|
||||
self.buffer[start..end].iter().collect()
|
||||
}
|
||||
|
||||
pub fn read_while(&mut self, predicate: fn(&char) -> bool) -> String {
|
||||
let mut s = String::from("");
|
||||
loop {
|
||||
@ -118,7 +127,7 @@ impl Reader {
|
||||
}
|
||||
|
||||
pub fn try_literal(&mut self, value: &str) -> bool {
|
||||
if self.remaining().starts_with(value.to_string().as_str()) {
|
||||
if self.peek_n(value.len()) == value {
|
||||
self.read_n(value.len());
|
||||
true
|
||||
} else {
|
||||
@ -126,16 +135,7 @@ impl Reader {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remaining(&self) -> String {
|
||||
self.buffer.as_slice()[self.state.cursor..self.buffer.len()]
|
||||
.iter()
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn slice(&self, start: usize, end: usize) -> String {
|
||||
self.buffer.as_slice()[start..end].iter().collect()
|
||||
}
|
||||
|
||||
// FIXME: explain this method, find a better name mayebe?
|
||||
pub fn from(&self, start: usize) -> String {
|
||||
let end = self.state.cursor;
|
||||
self.buffer.as_slice()[start..end].iter().collect()
|
||||
@ -155,7 +155,7 @@ mod tests {
|
||||
let mut reader = Reader::init("hi");
|
||||
assert_eq!(reader.state.cursor, 0);
|
||||
assert!(!reader.is_eof());
|
||||
assert_eq!(reader.remaining(), "hi".to_string());
|
||||
assert_eq!(reader.peek_n(2), "hi".to_string());
|
||||
|
||||
assert_eq!(reader.read().unwrap(), 'h');
|
||||
assert_eq!(reader.state.cursor, 1);
|
||||
|
@ -110,7 +110,7 @@ mod tests {
|
||||
String::from("<users><user /></users>")
|
||||
);
|
||||
assert_eq!(reader.state.cursor, 23);
|
||||
assert_eq!(reader.remaining(), String::from("xx"));
|
||||
assert_eq!(reader.peek_n(2), String::from("xx"));
|
||||
|
||||
let mut reader = Reader::init("<?xml version=\"1.0\"?><users/>xxx");
|
||||
assert_eq!(
|
||||
|
Loading…
Reference in New Issue
Block a user