1use crate::query::queryable::Queryable;
2use crate::query::QueryPath;
3use std::fmt::{Display, Formatter};
4
5#[derive(Debug, Clone, PartialEq)]
8pub struct State<'a, T: Queryable> {
9 pub data: Data<'a, T>,
10 pub root: &'a T,
11}
12
13impl<'a, T: Queryable> Display for State<'a, T> {
14 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
15 write!(f, "{}", self.data)
16 }
17}
18
19impl<'a, T: Queryable> From<&'a T> for State<'a, T> {
20 fn from(root: &'a T) -> Self {
21 State::root(root)
22 }
23}
24
25impl<'a, T: Queryable> State<'a, T> {
26 pub fn bool(b: bool, root: &T) -> State<T> {
27 State::data(root, Data::Value(b.into()))
28 }
29
30 pub fn i64(i: i64, root: &T) -> State<T> {
31 State::data(root, Data::Value(i.into()))
32 }
33 pub fn str(v: &str, root: &'a T) -> State<'a, T> {
34 State::data(root, Data::Value(v.into()))
35 }
36
37 pub fn shift_to_root(self) -> State<'a, T> {
38 State::root(self.root)
39 }
40
41 pub fn root(root: &'a T) -> Self {
42 State {
43 root,
44 data: Data::new_ref(Pointer::new(root, "$".to_string())),
45 }
46 }
47
48 pub fn nothing(root: &'a T) -> Self {
49 State {
50 root,
51 data: Data::Nothing,
52 }
53 }
54
55 pub fn data(root: &'a T, data: Data<'a, T>) -> Self {
56 State { root, data }
57 }
58
59 pub fn ok_ref(self) -> Option<Vec<Pointer<'a, T>>> {
60 self.data.ok_ref()
61 }
62
63 pub fn ok_val(self) -> Option<T> {
64 match self.data {
65 Data::Value(v) => Some(v),
66 _ => None,
67 }
68 }
69
70 pub fn is_nothing(&self) -> bool {
71 matches!(&self.data, Data::Nothing)
72 }
73
74 pub fn reduce(self, other: State<'a, T>) -> State<'a, T> {
75 State {
76 root: self.root,
77 data: self.data.reduce(other.data),
78 }
79 }
80 pub fn flat_map<F>(self, f: F) -> State<'a, T>
81 where
82 F: Fn(Pointer<'a, T>) -> Data<'a, T>,
83 {
84 State {
85 root: self.root,
86 data: self.data.flat_map(f),
87 }
88 }
89}
90
91#[derive(Debug, Clone, PartialEq)]
94pub enum Data<'a, T: Queryable> {
95 Ref(Pointer<'a, T>),
96 Refs(Vec<Pointer<'a, T>>),
97 Value(T),
98 Nothing,
99}
100
101impl<'a, T: Queryable> Display for Data<'a, T> {
102 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
103 match self {
104 Data::Ref(p) => write!(f, "&{}", p),
105 Data::Refs(p) => write!(
106 f,
107 "{}",
108 p.iter()
109 .map(|ptr| ptr.to_string())
110 .collect::<Vec<_>>()
111 .join("; ")
112 ),
113 Data::Value(v) => write!(f, "{:?}", v),
114 Data::Nothing => write!(f, "Nothing"),
115 }
116 }
117}
118
119impl<'a, T: Queryable> Default for Data<'a, T> {
120 fn default() -> Self {
121 Data::Nothing
122 }
123}
124
125impl<'a, T: Queryable> Data<'a, T> {
126 pub fn reduce(self, other: Data<'a, T>) -> Data<'a, T> {
127 match (self, other) {
128 (Data::Ref(data), Data::Ref(data2)) => Data::Refs(vec![data, data2]),
129 (Data::Ref(data), Data::Refs(data_vec)) => {
130 Data::Refs(vec![data].into_iter().chain(data_vec).collect())
131 }
132 (Data::Refs(data_vec), Data::Ref(data)) => {
133 Data::Refs(data_vec.into_iter().chain(vec![data]).collect())
134 }
135 (Data::Refs(data_vec), Data::Refs(data_vec2)) => {
136 Data::Refs(data_vec.into_iter().chain(data_vec2).collect())
137 }
138 (d @ (Data::Ref(_) | Data::Refs(..)), Data::Nothing) => d,
139 (Data::Nothing, d @ (Data::Ref(_) | Data::Refs(..))) => d,
140 _ => Data::Nothing,
141 }
142 }
143
144 pub fn flat_map<F>(self, f: F) -> Data<'a, T>
145 where
146 F: Fn(Pointer<'a, T>) -> Data<'a, T>,
147 {
148 match self {
149 Data::Ref(data) => f(data),
150 Data::Refs(data_vec) => Data::Refs(
151 data_vec
152 .into_iter()
153 .flat_map(|data| match f(data) {
154 Data::Ref(data) => vec![data],
155 Data::Refs(data_vec) => data_vec,
156 _ => vec![],
157 })
158 .collect::<Vec<_>>(),
159 ),
160 _ => Data::Nothing,
161 }
162 }
163
164 pub fn ok_ref(self) -> Option<Vec<Pointer<'a, T>>> {
168 match self {
169 Data::Ref(data) => Some(vec![data]),
170 Data::Refs(data) => Some(data),
171 _ => None,
172 }
173 }
174
175 pub fn ok_val(self) -> Option<T> {
178 match self {
179 Data::Value(v) => Some(v),
180 _ => None,
181 }
182 }
183
184 pub fn new_ref(data: Pointer<'a, T>) -> Data<'a, T> {
185 Data::Ref(data)
186 }
187
188 pub fn new_refs(data: Vec<Pointer<'a, T>>) -> Data<'a, T> {
189 Data::Refs(data)
190 }
191}
192
193#[derive(Debug, Clone, PartialEq)]
196pub(crate) struct Pointer<'a, T: Queryable> {
197 pub inner: &'a T,
198 pub path: QueryPath,
199}
200
201fn normal_name_selector(name: &str) -> String {
204 let mut selector = String::with_capacity(name.len() + 2);
205 selector.push('\'');
206 for ch in name.chars() {
207 match ch {
208 '\u{0008}' => selector.push_str("\\b"),
209 '\u{000C}' => selector.push_str("\\f"),
210 '\n' => selector.push_str("\\n"),
211 '\r' => selector.push_str("\\r"),
212 '\t' => selector.push_str("\\t"),
213 '\'' => selector.push_str("\\'"),
214 '\\' => selector.push_str("\\\\"),
215 c if c < '\u{0020}' => selector.push_str(&format!("\\u{:04x}", c as u32)),
216 c => selector.push(c),
217 }
218 }
219 selector.push('\'');
220 selector
221}
222
223impl<'a, T: Queryable> Display for Pointer<'a, T> {
224 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
225 write!(f, "{:?}='{}'", self.inner, self.path)
226 }
227}
228
229impl<'a, T: Queryable> Pointer<'a, T> {
230 pub fn new(inner: &'a T, path: QueryPath) -> Self {
231 Pointer { inner, path }
232 }
233
234 pub fn key(inner: &'a T, path: QueryPath, key: &str) -> Self {
235 Pointer {
236 inner,
237 path: format!("{}[{}]", path, normal_name_selector(key)),
238 }
239 }
240 pub fn idx(inner: &'a T, path: QueryPath, index: usize) -> Self {
241 Pointer {
242 inner,
243 path: format!("{}[{}]", path, index),
244 }
245 }
246
247 pub fn empty(inner: &'a T) -> Self {
248 Pointer {
249 inner,
250 path: String::new(),
251 }
252 }
253
254 pub fn is_internal(&self) -> bool {
255 self.path.is_empty()
256 }
257}