Skip to content

Commit 6a409c4

Browse files
author
meir
committed
First commit, added rust code.
1 parent 68b4888 commit 6a409c4

File tree

7 files changed

+1619
-0
lines changed

7 files changed

+1619
-0
lines changed

Cargo.toml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[package]
2+
name = "JsonPathCalculator"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
pest = "2.1"
10+
pest_derive = "2.1"
11+
serde = { version = "1.0", features = ["derive"] }
12+
serde_json = { version = "1.0", features = ["preserve_order"] }
13+
ijson = "0.1.3"
14+
15+
[lib]
16+
name = "jsonpath_calculator"
17+
path = "src/lib.rs"
18+
crate-type = ["cdylib", "rlib"]

src/grammer.pest

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
literal = @{(!("."|"*"|"\""|"'"|"["|"]"|"="|" "|"("|")"|"{"|"}"|"|"|"<"|">"|"!") ~ ANY)+}
2+
3+
string = _{"\"" ~ string_value ~ "\""}
4+
string_value = @{(!("\"") ~ ANY)+}
5+
6+
string_list = {string ~ ("," ~ string)*}
7+
8+
number = @{"-"? ~ ASCII_NONZERO_DIGIT ~ ASCII_DIGIT* | "-"? ~ ASCII_DIGIT}
9+
10+
decimal = @{number ~ ("." ~ ASCII_DIGIT+)?}
11+
12+
numbers_list = {number ~ ("," ~ number)*}
13+
14+
numbers_range = {full_range | right_range | all_range | left_range }
15+
right_range = {":" ~ number}
16+
all_range = {":"}
17+
left_range = {number ~ ":"}
18+
full_range = {number ~ ":" ~ number}
19+
20+
from_current = {"@" ~ root?}
21+
from_root = {"$" ~ root?}
22+
23+
select_term = _{from_current | from_root}
24+
25+
op = _{ge | gt | le | lt | eq | ne | re}
26+
ge = @{">="}
27+
gt = @{">"}
28+
le = @{"<="}
29+
lt = @{"<"}
30+
eq = @{"=="}
31+
ne = @{"!="}
32+
re = @{"=~"}
33+
34+
term = _{select_term | decimal | string}
35+
36+
single_filter = {term ~ op ~ term}
37+
38+
filter_relation = _{and | or}
39+
and = {"&&"}
40+
or = {"||"}
41+
42+
inner_filter = _{single_filter | "(" ~ filter ~ ")"}
43+
44+
filter = {inner_filter ~ (filter_relation ~ inner_filter)?}
45+
46+
all = {"*"}
47+
48+
full_scan = {".."}
49+
50+
bracket = _{numbers_range | numbers_list | string_list | all | "?" ~ filter}
51+
52+
element = _{full_scan ~ (literal | all | "[" ~ bracket ~ "]") | "." ~ literal | "." ~ all | ("."? ~ "[" ~ bracket ~ "]")}
53+
54+
first_element = _{literal | all}
55+
56+
root = {(element|first_element) ~ (element)*}
57+
58+
query = _{SOI ~ "$" ~ root? ~ EOI}
59+
60+
WHITESPACE = _{ " " }

src/json_node.rs

Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
use crate::select_value::{SelectValue, SelectValueType};
2+
use serde_json::Value;
3+
use ijson::{IValue, ValueType};
4+
5+
impl SelectValue for Value {
6+
fn get_type(&self) -> SelectValueType {
7+
match self {
8+
Value::Bool(_) => SelectValueType::Bool,
9+
Value::String(_) => SelectValueType::String,
10+
Value::Null => SelectValueType::Null,
11+
Value::Array(_) => SelectValueType::Array,
12+
Value::Object(_) => SelectValueType::Object,
13+
Value::Number(n) => {
14+
if n.is_i64() {
15+
SelectValueType::Long
16+
} else if n.is_u64() {
17+
SelectValueType::Long
18+
} else if n.is_f64() {
19+
SelectValueType::Double
20+
} else {
21+
panic!("bad type for Number value");
22+
}
23+
}
24+
}
25+
}
26+
27+
fn contains_key(&self, key: &str) -> bool {
28+
match self {
29+
Value::Object(o) => o.contains_key(key),
30+
_ => false,
31+
}
32+
}
33+
34+
fn values<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a Self> + 'a>> {
35+
match self {
36+
Value::Array(arr) => Some(Box::new(arr.iter())),
37+
Value::Object(o) => Some(Box::new(o.values())),
38+
_ => None,
39+
}
40+
}
41+
42+
fn keys<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a str> + 'a>> {
43+
match self {
44+
Value::Object(o) => Some(Box::new(o.keys().map(|k| &k[..]))),
45+
_ => None,
46+
}
47+
}
48+
49+
fn items<'a>(&'a self) -> Option<Box<dyn Iterator<Item = (&'a str, &'a Self)> + 'a>>{
50+
match self {
51+
Value::Object(o) => Some(Box::new(o.iter().map(|(k,v)| (&k[..],v)))),
52+
_ => None,
53+
}
54+
}
55+
56+
fn len(&self) -> Option<usize> {
57+
match self {
58+
Value::Array(arr) => Some(arr.len()),
59+
Value::Object(obj) => Some(obj.len()),
60+
_ => None,
61+
}
62+
}
63+
64+
fn get_key<'a>(&'a self, key: &str) -> Option<&'a Self> {
65+
match self {
66+
Value::Object(o) => o.get(key),
67+
_ => None,
68+
}
69+
}
70+
71+
fn get_index<'a>(&'a self, index: usize) -> Option<&'a Self> {
72+
match self {
73+
Value::Array(arr) => arr.get(index),
74+
_ => None,
75+
}
76+
}
77+
78+
fn is_array(&self) -> bool {
79+
match self {
80+
Value::Array(_) => true,
81+
_ => false,
82+
}
83+
}
84+
85+
fn get_str(&self) -> String {
86+
match self {
87+
Value::String(s) => s.to_string(),
88+
_ => {
89+
panic!("not a string");
90+
}
91+
}
92+
}
93+
94+
fn as_str<'a>(&'a self) -> &'a str {
95+
match self {
96+
Value::String(s) => s.as_str(),
97+
_ => {
98+
panic!("not a string");
99+
}
100+
}
101+
}
102+
103+
fn get_bool(&self) -> bool {
104+
match self {
105+
Value::Bool(b) => *b,
106+
_ => {
107+
assert!(false, "not a bool");
108+
false
109+
}
110+
}
111+
}
112+
113+
fn get_long(&self) -> i64 {
114+
match self {
115+
Value::Number(n) => {
116+
if n.is_i64() || n.is_u64() {
117+
n.as_i64().unwrap()
118+
} else {
119+
assert!(false, "not a long");
120+
0
121+
}
122+
}
123+
_ => {
124+
assert!(false, "not a long");
125+
0
126+
}
127+
}
128+
}
129+
130+
fn get_double(&self) -> f64 {
131+
match self {
132+
Value::Number(n) => {
133+
if n.is_f64() {
134+
n.as_f64().unwrap()
135+
} else {
136+
assert!(false, "not a double");
137+
0.1
138+
}
139+
}
140+
_ => {
141+
assert!(false, "not a double");
142+
0.1
143+
}
144+
}
145+
}
146+
}
147+
148+
impl SelectValue for IValue {
149+
fn get_type(&self) -> SelectValueType {
150+
match self.type_() {
151+
ValueType::Bool => SelectValueType::Bool,
152+
ValueType::String => SelectValueType::String,
153+
ValueType::Null => SelectValueType::Null,
154+
ValueType::Array => SelectValueType::Array,
155+
ValueType::Object => SelectValueType::Object,
156+
ValueType::Number => {
157+
let num = self.as_number().unwrap();
158+
if num.has_decimal_point() {
159+
SelectValueType::Double
160+
} else {
161+
SelectValueType::Long
162+
}
163+
}
164+
}
165+
}
166+
167+
fn contains_key(&self, key: &str) -> bool {
168+
match self.as_object() {
169+
Some(o) => o.contains_key(key),
170+
_ => false,
171+
}
172+
}
173+
174+
fn values<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a Self> + 'a>> {
175+
if let Some(arr) = self.as_array(){
176+
Some(Box::new(arr.iter()))
177+
} else if let Some(o) = self.as_object(){
178+
Some(Box::new(o.values()))
179+
} else {
180+
None
181+
}
182+
}
183+
184+
fn keys<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a str> + 'a>> {
185+
match self.as_object() {
186+
Some(o) => Some(Box::new(o.keys().map(|k| &k[..]))),
187+
_ => None,
188+
}
189+
}
190+
191+
fn items<'a>(&'a self) -> Option<Box<dyn Iterator<Item = (&'a str, &'a Self)> + 'a>>{
192+
match self.as_object() {
193+
Some(o) => Some(Box::new(o.iter().map(|(k,v)| (&k[..],v)))),
194+
_ => None,
195+
}
196+
}
197+
198+
fn len(&self) -> Option<usize> {
199+
if let Some(arr) = self.as_array(){
200+
Some(arr.len())
201+
} else if let Some(obj) = self.as_object(){
202+
Some(obj.len())
203+
} else {
204+
None
205+
}
206+
}
207+
208+
fn get_key<'a>(&'a self, key: &str) -> Option<&'a Self> {
209+
match self.as_object() {
210+
Some(o) => o.get(key),
211+
_ => None,
212+
}
213+
}
214+
215+
fn get_index<'a>(&'a self, index: usize) -> Option<&'a Self> {
216+
match self.as_array() {
217+
Some(arr) => arr.get(index),
218+
_ => None,
219+
}
220+
}
221+
222+
fn is_array(&self) -> bool {
223+
self.is_array()
224+
}
225+
226+
fn get_str(&self) -> String {
227+
match self.as_string() {
228+
Some(s) => s.to_string(),
229+
_ => {
230+
panic!("not a string");
231+
}
232+
}
233+
}
234+
235+
fn as_str<'a>(&'a self) -> &'a str {
236+
match self.as_string() {
237+
Some(s) => s.as_str(),
238+
_ => {
239+
panic!("not a string");
240+
}
241+
}
242+
}
243+
244+
fn get_bool(&self) -> bool {
245+
match self.to_bool() {
246+
Some(b) => b,
247+
_ => {
248+
assert!(false, "not a bool");
249+
false
250+
}
251+
}
252+
}
253+
254+
fn get_long(&self) -> i64 {
255+
match self.as_number() {
256+
Some(n) => {
257+
if n.has_decimal_point() {
258+
assert!(false, "not a long");
259+
0
260+
} else {
261+
n.to_i64().unwrap()
262+
}
263+
}
264+
_ => {
265+
assert!(false, "not a long");
266+
0
267+
}
268+
}
269+
}
270+
271+
fn get_double(&self) -> f64 {
272+
match self.as_number() {
273+
Some(n) => {
274+
if n.has_decimal_point() {
275+
n.to_f64().unwrap()
276+
} else {
277+
assert!(false, "not a double");
278+
0.1
279+
}
280+
}
281+
_ => {
282+
assert!(false, "not a double");
283+
0.1
284+
}
285+
}
286+
}
287+
}

0 commit comments

Comments
 (0)