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
201impl<'a, T: Queryable> Display for Pointer<'a, T> {
202 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
203 write!(f, "{:?}='{}'", self.inner, self.path)
204 }
205}
206
207impl<'a, T: Queryable> Pointer<'a, T> {
208 pub fn new(inner: &'a T, path: QueryPath) -> Self {
209 Pointer { inner, path }
210 }
211
212 pub fn key(inner: &'a T, path: QueryPath, key: &str) -> Self {
213 let path = if key.starts_with("'") && key.ends_with("'") {
214 format!("{}[{}]", path, key)
215 } else {
216 format!("{}['{}']", path, key)
217 };
218
219 Pointer { inner, path }
220 }
221 pub fn idx(inner: &'a T, path: QueryPath, index: usize) -> Self {
222 Pointer {
223 inner,
224 path: format!("{}[{}]", path, index),
225 }
226 }
227
228 pub fn empty(inner: &'a T) -> Self {
229 Pointer {
230 inner,
231 path: String::new(),
232 }
233 }
234
235 pub fn is_internal(&self) -> bool {
236 self.path.is_empty()
237 }
238}