기본구현 완료

This commit is contained in:
freestrings 2019-02-26 23:04:04 +09:00
parent 0534dad755
commit 87a226451a
8 changed files with 70 additions and 10 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "rs-jsonpath" name = "rs-jsonpath"
version = "1.0.0" version = "0.1.0"
authors = ["freestrings <freestrings@gmail.com>"] authors = ["freestrings <freestrings@gmail.com>"]
[dependencies] [dependencies]
@ -12,3 +12,11 @@ indexmap = "1.0.2"
[dev-dependencies] [dev-dependencies]
bencher = "0.1.5" bencher = "0.1.5"
[lib]
name = "jsonpath"
path = "src/lib.rs"
[[bin]]
name = "jsonpath"
path = "src/bin.rs"

View File

@ -1,5 +1,5 @@
#![feature(test)] #![feature(test)]
extern crate rs_jsonpath; extern crate jsonpath;
extern crate serde_json; extern crate serde_json;
extern crate test; extern crate test;

2
src/bin.rs Normal file
View File

@ -0,0 +1,2 @@
fn main() {
}

View File

@ -1,9 +1,8 @@
mod cmp; mod cmp;
mod term; mod term;
mod value_filter; pub mod value_filter;
mod value_wrapper; mod value_wrapper;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
extern crate env_logger; extern crate env_logger;

View File

@ -260,6 +260,15 @@ impl JsonValueFilter {
}) })
} }
pub fn new_from_value(json: Value) -> result::Result<Self, String> {
Ok(JsonValueFilter {
json: Rc::new(Box::new(json)),
filter_stack: Vec::new(),
token_stack: Vec::new(),
term_stack: Vec::new(),
})
}
fn is_peek_token_array(&self) -> bool { fn is_peek_token_array(&self) -> bool {
if let Some(ParseToken::Array) = self.token_stack.last() { if let Some(ParseToken::Array) = self.token_stack.last() {
true true
@ -309,6 +318,13 @@ impl JsonValueFilter {
} }
} }
pub fn take_value(&mut self) -> Value {
match self.filter_stack.last_mut() {
Some(v) => v.vw.get_val_mut().take(),
_ => Value::Null
}
}
fn token_union<F: ArrayIndex>(&mut self, indices: Vec<F>) { fn token_union<F: ArrayIndex>(&mut self, indices: Vec<F>) {
self.token_stack.pop(); self.token_stack.pop();

View File

@ -1,4 +1,4 @@
mod path_reader; mod path_reader;
mod tokenizer; mod tokenizer;
mod parser; pub mod parser;
mod json_filter; pub mod json_filter;

View File

@ -34,7 +34,7 @@ mod utils {
} }
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Clone)]
pub enum ParseToken { pub enum ParseToken {
// '$' // '$'
Absolute, Absolute,
@ -64,7 +64,7 @@ pub enum ParseToken {
Eof, Eof,
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Clone)]
pub enum FilterToken { pub enum FilterToken {
Equal, Equal,
NotEqual, NotEqual,
@ -76,7 +76,7 @@ pub enum FilterToken {
Or, Or,
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct Node { pub struct Node {
left: Option<Box<Node>>, left: Option<Box<Node>>,
right: Option<Box<Node>>, right: Option<Box<Node>>,
@ -92,6 +92,10 @@ impl<'a> Parser<'a> {
Parser { tokenizer: PreloadedTokenizer::new(input) } Parser { tokenizer: PreloadedTokenizer::new(input) }
} }
pub fn compile(&mut self) -> Result<Node> {
Ok(self.json_path()?)
}
pub fn parse<V: NodeVisitor>(&mut self, visitor: &mut V) -> Result<()> { pub fn parse<V: NodeVisitor>(&mut self, visitor: &mut V) -> Result<()> {
let node = self.json_path()?; let node = self.json_path()?;
visitor.visit(node); visitor.visit(node);

View File

@ -6,4 +6,35 @@ extern crate serde;
extern crate serde_json; extern crate serde_json;
extern crate core; extern crate core;
extern crate indexmap; extern crate indexmap;
pub mod jsonpath;
mod jsonpath;
use jsonpath::parser::*;
use jsonpath::json_filter::value_filter::*;
use std::result;
use serde_json::Value;
type Result = result::Result<Value, String>;
pub fn compile<'a>(path: &'a str) -> impl FnMut(Value) -> Result + 'a {
let mut parser = Parser::new(path);
let node = parser.compile();
move |json| {
match &node {
Ok(n) => {
let mut jf = JsonValueFilter::new_from_value(json)?;
jf.visit(n.clone());
Ok(jf.take_value())
},
Err(e) => Err(e.clone())
}
}
}
pub fn filter(json: Value, path: &str) -> Result {
let mut jf = JsonValueFilter::new_from_value(json)?;
let mut parser = Parser::new(path);
parser.parse(&mut jf)?;
Ok(jf.take_value())
}