Stable 버전에서 컴파일 에러 수정

This commit is contained in:
freestrings
2019-06-11 18:40:18 +09:00
parent 2e9e0ac6fc
commit 766be8cab2
5 changed files with 146 additions and 128 deletions

View File

@ -1,5 +1,4 @@
#![feature(test)]
extern crate bencher;
extern crate jsonpath_lib as jsonpath;
extern crate serde;

View File

@ -76,7 +76,6 @@ pub struct Node {
pub struct Parser;
impl Parser {
pub fn compile(input: &str) -> ParseResult<Node> {
let mut tokenizer = TokenReader::new(input);
Ok(Self::json_path(&mut tokenizer)?)
@ -531,14 +530,22 @@ impl Parser {
}
}
fn peek_key(tokenizer: &mut TokenReader) -> Option<String> {
if let Ok(Token::Key(_, k)) = tokenizer.peek_token() {
Some(k.clone())
} else {
None
}
}
fn term(tokenizer: &mut TokenReader) -> ParseResult<Node> {
debug!("#term");
match tokenizer.peek_token() {
Ok(Token::At(_)) => {
if tokenizer.peek_is(AT) {
Self::eat_token(tokenizer);
let node = Self::node(ParseToken::Relative);
match tokenizer.peek_token() {
return match tokenizer.peek_token() {
Ok(Token::Whitespace(_, _)) => {
Self::eat_whitespace(tokenizer);
Ok(node)
@ -546,28 +553,31 @@ impl Parser {
_ => {
Self::paths(node, tokenizer)
}
};
}
if tokenizer.peek_is(ABSOLUTE) {
return Self::json_path(tokenizer);
}
Ok(Token::Absolute(_)) => {
Self::json_path(tokenizer)
if tokenizer.peek_is(DOUBLE_QUOTA) || tokenizer.peek_is(SINGLE_QUOTA) {
return Self::array_quota_value(tokenizer);
}
Ok(Token::DoubleQuoted(_, _))
| Ok(Token::SingleQuoted(_, _)) => {
Self::array_quota_value(tokenizer)
}
Ok(Token::Key(_, k)) => {
match k.chars().next() {
if tokenizer.peek_is(KEY) {
return match Self::peek_key(tokenizer) {
Some(key) => match key.chars().next() {
Some(ch) => match ch {
'-' | '0'...'9' => Self::term_num(tokenizer),
_ => Self::boolean(tokenizer)
}
_ => Err(tokenizer.err_msg())
},
_ => Err(tokenizer.err_msg())
};
}
}
_ => {
Err(tokenizer.err_msg())
}
}
return Err(tokenizer.err_msg());
}
fn op(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> {

View File

@ -3,29 +3,29 @@ use std::result::Result;
use super::path_reader::{PathReader, ReaderError};
const ABSOLUTE: &'static str = "$";
const DOT: &'static str = ".";
const AT: &'static str = "@";
const OPEN_ARRAY: &'static str = "[";
const CLOSE_ARRAY: &'static str = "]";
const ASTERISK: &'static str = "*";
const QUESTION: &'static str = "?";
const COMMA: &'static str = ",";
const SPLIT: &'static str = ":";
const OPEN_PARENTHESIS: &'static str = "(";
const CLOSE_PARENTHESIS: &'static str = ")";
const KEY: &'static str = "Key";
const DOUBLE_QUOTA: &'static str = "\"";
const SINGLE_QUOTA: &'static str = "'";
const EQUAL: &'static str = "==";
const GREATER_OR_EQUAL: &'static str = ">=";
const GREATER: &'static str = ">";
const LITTLE: &'static str = "<";
const LITTLE_OR_EQUAL: &'static str = "<=";
const NOT_EQUAL: &'static str = "!=";
const AND: &'static str = "&&";
const OR: &'static str = "||";
const WHITESPACE: &'static str = " ";
pub const ABSOLUTE: &'static str = "$";
pub const DOT: &'static str = ".";
pub const AT: &'static str = "@";
pub const OPEN_ARRAY: &'static str = "[";
pub const CLOSE_ARRAY: &'static str = "]";
pub const ASTERISK: &'static str = "*";
pub const QUESTION: &'static str = "?";
pub const COMMA: &'static str = ",";
pub const SPLIT: &'static str = ":";
pub const OPEN_PARENTHESIS: &'static str = "(";
pub const CLOSE_PARENTHESIS: &'static str = ")";
pub const KEY: &'static str = "Key";
pub const DOUBLE_QUOTA: &'static str = "\"";
pub const SINGLE_QUOTA: &'static str = "'";
pub const EQUAL: &'static str = "==";
pub const GREATER_OR_EQUAL: &'static str = ">=";
pub const GREATER: &'static str = ">";
pub const LITTLE: &'static str = "<";
pub const LITTLE_OR_EQUAL: &'static str = "<=";
pub const NOT_EQUAL: &'static str = "!=";
pub const AND: &'static str = "&&";
pub const OR: &'static str = "||";
pub const WHITESPACE: &'static str = " ";
const CH_DOLLA: char = '$';
const CH_DOT: char = '.';
@ -91,6 +91,10 @@ impl Token {
self.to_simple() == other.to_simple()
}
pub fn simple_eq(&self, str_token: &str) -> bool {
self.to_simple() == str_token
}
fn to_simple(&self) -> &'static str {
match self {
Token::Absolute(_) => ABSOLUTE,
@ -305,6 +309,13 @@ impl<'a> TokenReader<'a> {
}
}
pub fn peek_is(&self, simple_token: &str) -> bool {
match self.peek_token() {
Ok(t) => t.simple_eq(simple_token),
_ => false
}
}
pub fn peek_token(&self) -> Result<&Token, TokenError> {
match self.tokens.last() {
Some((_, t)) => {

View File

@ -1004,6 +1004,49 @@ pub struct SelectorMut {
value: Option<Value>,
}
fn replace_value<F: FnMut(&Value) -> Value>(tokens: Vec<String>, value: &mut Value, fun: &mut F) {
let mut target = value;
for (i, token) in tokens.iter().enumerate() {
let target_once = target;
let is_last = i == tokens.len() - 1;
let target_opt = match *target_once {
Value::Object(ref mut map) => {
if is_last {
let v = if let Some(v) = map.get(token) {
fun(v)
} else {
return;
};
map.insert(token.clone(), v);
return;
}
map.get_mut(token)
}
Value::Array(ref mut vec) => {
if let Ok(x) = token.parse::<usize>() {
if is_last {
let v = { fun(&vec[x]) };
vec[x] = v;
return;
}
vec.get_mut(x)
} else {
None
}
}
_ => None,
};
if let Some(t) = target_opt {
target = t;
} else {
break;
}
}
}
impl SelectorMut {
pub fn new() -> Self {
SelectorMut { path: None, value: None }
@ -1014,11 +1057,6 @@ impl SelectorMut {
Ok(self)
}
pub fn compiled_path(&mut self, node: Node) -> &mut Self {
self.path = Some(node);
self
}
pub fn value(&mut self, value: Value) -> &mut Self {
self.value = Some(value);
self
@ -1080,13 +1118,8 @@ impl SelectorMut {
self.replace_with(&mut |_| Value::Null)
}
pub fn replace_with<F: FnMut(&Value) -> Value>(&mut self, fun: &mut F) -> Result<&mut Self, JsonPathError> {
if self.path.is_none() {
return Err(JsonPathError::EmptyPath);
}
let node = self.path.take().unwrap();
fn select(&self) -> Result<Vec<&Value>, JsonPathError> {
if let Some(node) = &self.path {
let mut selector = Selector::new();
selector.compiled_path(&node);
@ -1094,62 +1127,24 @@ impl SelectorMut {
selector.value(value);
}
let result = selector.select();
self.path = Some(node);
let paths = self.compute_paths(result?);
if let Some(mut value) = self.value.take() {
for tokens in paths {
self.replace_value(tokens, &mut value, fun);
Ok(selector.select()?)
} else {
Err(JsonPathError::EmptyPath)
}
}
pub fn replace_with<F: FnMut(&Value) -> Value>(&mut self, fun: &mut F) -> Result<&mut Self, JsonPathError> {
let paths = {
let result = self.select()?;
self.compute_paths(result)
};
if let Some(ref mut value) = &mut self.value {
for tokens in paths {
replace_value(tokens, value, fun);
}
self.value = Some(value);
}
Ok(self)
}
fn replace_value<F: FnMut(&Value) -> Value>(&mut self, tokens: Vec<String>, value: &mut Value, fun: &mut F) {
let mut target = value;
for (i, token) in tokens.iter().enumerate() {
let target_once = target;
let is_last = i == tokens.len() - 1;
let target_opt = match *target_once {
Value::Object(ref mut map) => {
if is_last {
let v = if let Some(v) = map.get(token) {
fun(v)
} else {
return;
};
map.insert(token.clone(), v);
return;
}
map.get_mut(token)
}
Value::Array(ref mut vec) => {
if let Ok(x) = token.parse::<usize>() {
if is_last {
let v = &vec[x];
vec[x] = fun(v);
return;
}
vec.get_mut(x)
} else {
None
}
}
_ => None,
};
if let Some(t) = target_opt {
target = t;
} else {
break;
}
}
}
}

View File

@ -86,15 +86,18 @@ pub fn compile(path: &str) -> JsValue {
let node = Parser::compile(path);
let cb = Closure::wrap(Box::new(move |js_value: JsValue| {
let mut selector = _Selector::new();
match &node {
Ok(node) => selector.compiled_path(node),
Err(e) => return JsValue::from_str(&format!("{:?}", JsonPathError::Path(e.clone())))
};
let json = match into_serde_json(&js_value) {
Ok(json) => json,
Err(e) => return JsValue::from_str(&format!("{:?}", JsonPathError::Serde(e)))
};
let mut selector = _Selector::new();
match &node {
Ok(node) => selector.compiled_path(node),
Err(e) => return JsValue::from_str(&format!("{:?}", JsonPathError::Path(e.clone())))
};
match selector.value(&json).select() {
Ok(ret) => match JsValue::from_serde(&ret) {
Ok(ret) => ret,