rs_pixel/util/
generic_json.rs1use serde_json::{Map, Value};
2
3pub trait Raw {
4 fn raw(&self) -> &Value;
5}
6
7pub trait Property {
8 fn get_property(&self, full_path: &str) -> Option<&Value>;
9 fn get_str_property(&self, full_path: &str) -> Option<&str>;
10 fn get_string_property(&self, full_path: &str) -> Option<String>;
11 fn get_int_property(&self, full_path: &str) -> Option<i64>;
12 fn get_float_property(&self, full_path: &str) -> Option<f64>;
13 fn get_array_property(&self, full_path: &str) -> Option<&Vec<Value>>;
14 fn get_object_property(&self, full_path: &str) -> Option<&Map<String, Value>>;
15}
16
17impl<T> Property for T
18where
19 T: Raw,
20{
21 fn get_property(&self, full_path: &str) -> Option<&Value> {
22 if full_path.is_empty() {
23 return Some(self.raw());
24 }
25
26 let paths = full_path.split('.');
27 let mut cur_raw = self.raw();
28
29 for path in paths {
30 if cur_raw.is_array() {
31 match path.parse::<usize>() {
32 Ok(idx) => {
33 match cur_raw.get(idx) {
34 Some(new_raw) => cur_raw = new_raw,
35 None => return None,
36 };
37 continue;
38 }
39 Err(_) => return None,
40 }
41 }
42
43 match cur_raw.get(path) {
44 Some(new_raw) => cur_raw = new_raw,
45 None => return None,
46 }
47 }
48
49 Some(cur_raw)
50 }
51
52 fn get_str_property(&self, full_path: &str) -> Option<&str> {
53 self.get_property(full_path)
54 .and_then(serde_json::Value::as_str)
55 }
56
57 fn get_string_property(&self, full_path: &str) -> Option<String> {
58 self.get_property(full_path)
59 .and_then(serde_json::Value::as_str)
60 .map(std::string::ToString::to_string)
61 }
62
63 fn get_int_property(&self, full_path: &str) -> Option<i64> {
64 self.get_property(full_path).and_then(|v| {
65 if v.is_i64() {
66 v.as_i64()
67 } else {
68 v.as_f64().map(|f| f as i64)
69 }
70 })
71 }
72
73 fn get_float_property(&self, full_path: &str) -> Option<f64> {
74 self.get_property(full_path).and_then(|v| {
75 if v.is_f64() {
76 v.as_f64()
77 } else {
78 v.as_i64().map(|f| f as f64)
79 }
80 })
81 }
82
83 fn get_array_property(&self, full_path: &str) -> Option<&Vec<Value>> {
84 self.get_property(full_path)
85 .and_then(serde_json::Value::as_array)
86 }
87
88 fn get_object_property(&self, full_path: &str) -> Option<&Map<String, Value>> {
89 self.get_property(full_path)
90 .and_then(serde_json::Value::as_object)
91 }
92}
93
94impl Raw for Value {
95 fn raw(&self) -> &Value {
96 self
97 }
98}