1 use std::collections::HashMap;
2
3 use winnow::prelude::*;
4 use winnow::{
5 ascii::{alphanumeric1 as alphanumeric, escaped, float},
6 combinator::alt,
7 combinator::cut_err,
8 combinator::separated,
9 combinator::{preceded, separated_pair, terminated},
10 error::ParserError,
11 error::StrContext,
12 stream::Offset,
13 token::one_of,
14 token::{tag, take_while},
15 };
16
17 use std::cell::Cell;
18 use std::str;
19
20 #[derive(Clone, Debug)]
21 pub struct JsonValue<'a, 'b> {
22 input: &'a str,
23 pub offset: &'b Cell<usize>,
24 }
25
26 impl<'a, 'b: 'a> JsonValue<'a, 'b> {
new(input: &'a str, offset: &'b Cell<usize>) -> JsonValue<'a, 'b>27 pub fn new(input: &'a str, offset: &'b Cell<usize>) -> JsonValue<'a, 'b> {
28 JsonValue { input, offset }
29 }
30
offset(&self, input: &'a str)31 pub fn offset(&self, input: &'a str) {
32 let offset = input.offset_from(&self.input);
33 self.offset.set(offset);
34 }
35
data(&self) -> &'a str36 pub fn data(&self) -> &'a str {
37 &self.input[self.offset.get()..]
38 }
39
string(&self) -> Option<&'a str>40 pub fn string(&self) -> Option<&'a str> {
41 println!("string()");
42 let mut data = self.data();
43 match string(&mut data) {
44 Ok(s) => {
45 self.offset(data);
46 println!("-> {}", s);
47 Some(s)
48 }
49 _ => None,
50 }
51 }
52
boolean(&self) -> Option<bool>53 pub fn boolean(&self) -> Option<bool> {
54 println!("boolean()");
55 let mut data = self.data();
56 match boolean(&mut data) {
57 Ok(o) => {
58 self.offset(data);
59 println!("-> {}", o);
60 Some(o)
61 }
62 _ => None,
63 }
64 }
65
number(&self) -> Option<f64>66 pub fn number(&self) -> Option<f64> {
67 println!("number()");
68 let mut data = self.data();
69 match float::<_, _, ()>.parse_next(&mut data) {
70 Ok(o) => {
71 self.offset(data);
72 println!("-> {}", o);
73 Some(o)
74 }
75 _ => None,
76 }
77 }
78
array(&self) -> Option<impl Iterator<Item = JsonValue<'a, 'b>>>79 pub fn array(&self) -> Option<impl Iterator<Item = JsonValue<'a, 'b>>> {
80 println!("array()");
81
82 let mut data = self.data();
83 match tag::<_, _, ()>("[").parse_next(&mut data) {
84 Err(_) => None,
85 Ok(_) => {
86 println!("[");
87 self.offset(data);
88 let mut first = true;
89 let mut done = false;
90 let mut previous = std::usize::MAX;
91
92 let v = self.clone();
93
94 Some(std::iter::from_fn(move || {
95 if done {
96 return None;
97 }
98
99 // if we ignored one of the items, skip over the value
100 if v.offset.get() == previous {
101 println!("skipping value");
102 if value(&mut data).is_ok() {
103 v.offset(data);
104 }
105 }
106
107 if tag::<_, _, ()>("]").parse_next(&mut data).is_ok() {
108 println!("]");
109 v.offset(data);
110 done = true;
111 return None;
112 }
113
114 if first {
115 first = false;
116 } else {
117 match tag::<_, _, ()>(",").parse_next(&mut data) {
118 Ok(_) => {
119 println!(",");
120 v.offset(data);
121 }
122 Err(_) => {
123 done = true;
124 return None;
125 }
126 }
127 }
128
129 println!("-> {}", v.data());
130 previous = v.offset.get();
131 Some(v.clone())
132 }))
133 }
134 }
135 }
136
object(&self) -> Option<impl Iterator<Item = (&'a str, JsonValue<'a, 'b>)>>137 pub fn object(&self) -> Option<impl Iterator<Item = (&'a str, JsonValue<'a, 'b>)>> {
138 println!("object()");
139 let mut data = self.data();
140 match tag::<_, _, ()>("{").parse_next(&mut data) {
141 Err(_) => None,
142 Ok(_) => {
143 self.offset(data);
144
145 println!("{{");
146
147 let mut first = true;
148 let mut done = false;
149 let mut previous = std::usize::MAX;
150
151 let v = self.clone();
152
153 Some(std::iter::from_fn(move || {
154 if done {
155 return None;
156 }
157
158 // if we ignored one of the items, skip over the value
159 if v.offset.get() == previous {
160 println!("skipping value");
161 if value(&mut data).is_ok() {
162 v.offset(data);
163 }
164 }
165
166 if tag::<_, _, ()>("}").parse_next(&mut data).is_ok() {
167 println!("}}");
168 v.offset(data);
169 done = true;
170 return None;
171 }
172
173 if first {
174 first = false;
175 } else {
176 match tag::<_, _, ()>(",").parse_next(&mut data) {
177 Ok(_) => {
178 println!(",");
179 v.offset(data);
180 }
181 Err(_) => {
182 done = true;
183 return None;
184 }
185 }
186 }
187
188 match string(&mut data) {
189 Ok(key) => {
190 v.offset(data);
191
192 match tag::<_, _, ()>(":").parse_next(&mut data) {
193 Err(_) => None,
194 Ok(_) => {
195 v.offset(data);
196
197 previous = v.offset.get();
198
199 println!("-> {} => {}", key, v.data());
200 Some((key, v.clone()))
201 }
202 }
203 }
204 _ => None,
205 }
206 }))
207 }
208 }
209 }
210 }
211
sp<'a, E: ParserError<&'a str>>(i: &mut &'a str) -> PResult<&'a str, E>212 fn sp<'a, E: ParserError<&'a str>>(i: &mut &'a str) -> PResult<&'a str, E> {
213 let chars = " \t\r\n";
214
215 take_while(0.., move |c| chars.contains(c)).parse_next(i)
216 }
217
parse_str<'a, E: ParserError<&'a str>>(i: &mut &'a str) -> PResult<&'a str, E>218 fn parse_str<'a, E: ParserError<&'a str>>(i: &mut &'a str) -> PResult<&'a str, E> {
219 escaped(alphanumeric, '\\', one_of(['"', 'n', '\\'])).parse_next(i)
220 }
221
string<'s>(i: &mut &'s str) -> PResult<&'s str>222 fn string<'s>(i: &mut &'s str) -> PResult<&'s str> {
223 preceded('\"', cut_err(terminated(parse_str, '\"')))
224 .context(StrContext::Label("string"))
225 .parse_next(i)
226 }
227
boolean(input: &mut &str) -> PResult<bool>228 fn boolean(input: &mut &str) -> PResult<bool> {
229 alt(("false".map(|_| false), "true".map(|_| true))).parse_next(input)
230 }
231
array(i: &mut &str) -> PResult<()>232 fn array(i: &mut &str) -> PResult<()> {
233 preceded(
234 '[',
235 cut_err(terminated(
236 separated(0.., value, preceded(sp, ',')),
237 preceded(sp, ']'),
238 )),
239 )
240 .context(StrContext::Label("array"))
241 .parse_next(i)
242 }
243
key_value<'s>(i: &mut &'s str) -> PResult<(&'s str, ())>244 fn key_value<'s>(i: &mut &'s str) -> PResult<(&'s str, ())> {
245 separated_pair(preceded(sp, string), cut_err(preceded(sp, ':')), value).parse_next(i)
246 }
247
hash(i: &mut &str) -> PResult<()>248 fn hash(i: &mut &str) -> PResult<()> {
249 preceded(
250 '{',
251 cut_err(terminated(
252 separated(0.., key_value, preceded(sp, ',')),
253 preceded(sp, '}'),
254 )),
255 )
256 .context(StrContext::Label("map"))
257 .parse_next(i)
258 }
259
value(i: &mut &str) -> PResult<()>260 fn value(i: &mut &str) -> PResult<()> {
261 preceded(
262 sp,
263 alt((
264 hash,
265 array,
266 string.map(|_| ()),
267 float::<_, f64, _>.map(|_| ()),
268 boolean.map(|_| ()),
269 )),
270 )
271 .parse_next(i)
272 }
273
274 /// object(input) -> iterator over (key, `JsonValue`)
275 /// array(input) -> iterator over `JsonValue`
276 ///
277 /// JsonValue.string -> iterator over String (returns None after first successful call)
278 ///
279 /// object(input).filter(|(k, _)| k == "users").flatten(|(_, v)| v.object()).filter(|(k, _)| k == "city").flatten(|(_,v)| v.string())
main()280 fn main() {
281 /*let data = "{
282 \"users\": {
283 \"user1\" : { \"city\": \"Nantes\", \"country\": \"France\" },
284 \"user2\" : { \"city\": \"Bruxelles\", \"country\": \"Belgium\" },
285 \"user3\": { \"city\": \"Paris\", \"country\": \"France\", \"age\": 30 }
286 },
287 \"countries\": [\"France\", \"Belgium\"]
288 }";
289 */
290 let data = "{\"users\":{\"user1\":{\"city\":\"Nantes\",\"country\":\"France\"},\"user2\":{\"city\":\"Bruxelles\",\"country\":\"Belgium\"},\"user3\":{\"city\":\"Paris\",\"country\":\"France\",\"age\":30}},\"countries\":[\"France\",\"Belgium\"]}";
291
292 let offset = Cell::new(0);
293 {
294 let parser = JsonValue::new(data, &offset);
295
296 if let Some(o) = parser.object() {
297 let s: HashMap<&str, &str> = o
298 .filter(|(k, _)| *k == "users")
299 .filter_map(|(_, v)| v.object())
300 .flatten()
301 .filter_map(|(user, v)| v.object().map(|o| (user, o)))
302 .flat_map(|(user, o)| {
303 o.filter(|(k, _)| *k == "city")
304 .filter_map(move |(_, v)| v.string().map(|s| (user, s)))
305 })
306 .collect();
307
308 println!("res = {:?}", s);
309 }
310 };
311 }
312