16855e09eSopenharmony_ci#![cfg(feature = "alloc")]
26855e09eSopenharmony_ci
36855e09eSopenharmony_ciuse nom::{
46855e09eSopenharmony_ci  branch::alt,
56855e09eSopenharmony_ci  bytes::complete::{escaped, tag, take_while},
66855e09eSopenharmony_ci  character::complete::{alphanumeric1 as alphanumeric, char, one_of},
76855e09eSopenharmony_ci  combinator::{cut, map},
86855e09eSopenharmony_ci  error::{context, ParseError},
96855e09eSopenharmony_ci  multi::separated_list0,
106855e09eSopenharmony_ci  number::complete::double,
116855e09eSopenharmony_ci  sequence::{preceded, separated_pair, terminated},
126855e09eSopenharmony_ci  IResult,
136855e09eSopenharmony_ci};
146855e09eSopenharmony_ciuse std::collections::HashMap;
156855e09eSopenharmony_ci
166855e09eSopenharmony_ciuse std::cell::Cell;
176855e09eSopenharmony_ciuse std::str;
186855e09eSopenharmony_ci
196855e09eSopenharmony_ci#[derive(Clone, Debug)]
206855e09eSopenharmony_cipub struct JsonValue<'a, 'b> {
216855e09eSopenharmony_ci  input: &'a str,
226855e09eSopenharmony_ci  pub offset: &'b Cell<usize>,
236855e09eSopenharmony_ci}
246855e09eSopenharmony_ci
256855e09eSopenharmony_ciimpl<'a, 'b: 'a> JsonValue<'a, 'b> {
266855e09eSopenharmony_ci  pub fn new(input: &'a str, offset: &'b Cell<usize>) -> JsonValue<'a, 'b> {
276855e09eSopenharmony_ci    JsonValue { input, offset }
286855e09eSopenharmony_ci  }
296855e09eSopenharmony_ci
306855e09eSopenharmony_ci  pub fn offset(&self, input: &'a str) {
316855e09eSopenharmony_ci    let offset = input.as_ptr() as usize - self.input.as_ptr() as usize;
326855e09eSopenharmony_ci    self.offset.set(offset);
336855e09eSopenharmony_ci  }
346855e09eSopenharmony_ci
356855e09eSopenharmony_ci  pub fn data(&self) -> &'a str {
366855e09eSopenharmony_ci    &self.input[self.offset.get()..]
376855e09eSopenharmony_ci  }
386855e09eSopenharmony_ci
396855e09eSopenharmony_ci  pub fn string(&self) -> Option<&'a str> {
406855e09eSopenharmony_ci    println!("string()");
416855e09eSopenharmony_ci    match string(self.data()) {
426855e09eSopenharmony_ci      Ok((i, s)) => {
436855e09eSopenharmony_ci        self.offset(i);
446855e09eSopenharmony_ci        println!("-> {}", s);
456855e09eSopenharmony_ci        Some(s)
466855e09eSopenharmony_ci      }
476855e09eSopenharmony_ci      _ => None,
486855e09eSopenharmony_ci    }
496855e09eSopenharmony_ci  }
506855e09eSopenharmony_ci
516855e09eSopenharmony_ci  pub fn boolean(&self) -> Option<bool> {
526855e09eSopenharmony_ci    println!("boolean()");
536855e09eSopenharmony_ci    match boolean(self.data()) {
546855e09eSopenharmony_ci      Ok((i, o)) => {
556855e09eSopenharmony_ci        self.offset(i);
566855e09eSopenharmony_ci        println!("-> {}", o);
576855e09eSopenharmony_ci        Some(o)
586855e09eSopenharmony_ci      }
596855e09eSopenharmony_ci      _ => None,
606855e09eSopenharmony_ci    }
616855e09eSopenharmony_ci  }
626855e09eSopenharmony_ci
636855e09eSopenharmony_ci  pub fn number(&self) -> Option<f64> {
646855e09eSopenharmony_ci    println!("number()");
656855e09eSopenharmony_ci    match double::<_, ()>(self.data()) {
666855e09eSopenharmony_ci      Ok((i, o)) => {
676855e09eSopenharmony_ci        self.offset(i);
686855e09eSopenharmony_ci        println!("-> {}", o);
696855e09eSopenharmony_ci        Some(o)
706855e09eSopenharmony_ci      }
716855e09eSopenharmony_ci      _ => None,
726855e09eSopenharmony_ci    }
736855e09eSopenharmony_ci  }
746855e09eSopenharmony_ci
756855e09eSopenharmony_ci  pub fn array(&self) -> Option<impl Iterator<Item = JsonValue<'a, 'b>>> {
766855e09eSopenharmony_ci    println!("array()");
776855e09eSopenharmony_ci
786855e09eSopenharmony_ci    match tag::<_, _, ()>("[")(self.data()) {
796855e09eSopenharmony_ci      Err(_) => None,
806855e09eSopenharmony_ci      Ok((i, _)) => {
816855e09eSopenharmony_ci        println!("[");
826855e09eSopenharmony_ci        self.offset(i);
836855e09eSopenharmony_ci        let mut first = true;
846855e09eSopenharmony_ci        let mut done = false;
856855e09eSopenharmony_ci        let mut previous = std::usize::MAX;
866855e09eSopenharmony_ci
876855e09eSopenharmony_ci        let v = self.clone();
886855e09eSopenharmony_ci
896855e09eSopenharmony_ci        Some(std::iter::from_fn(move || {
906855e09eSopenharmony_ci          if done {
916855e09eSopenharmony_ci            return None;
926855e09eSopenharmony_ci          }
936855e09eSopenharmony_ci
946855e09eSopenharmony_ci          // if we ignored one of the items, skip over the value
956855e09eSopenharmony_ci          if v.offset.get() == previous {
966855e09eSopenharmony_ci            println!("skipping value");
976855e09eSopenharmony_ci            match value(v.data()) {
986855e09eSopenharmony_ci              Ok((i, _)) => {
996855e09eSopenharmony_ci                v.offset(i);
1006855e09eSopenharmony_ci              }
1016855e09eSopenharmony_ci              Err(_) => {}
1026855e09eSopenharmony_ci            }
1036855e09eSopenharmony_ci          }
1046855e09eSopenharmony_ci
1056855e09eSopenharmony_ci          match tag::<_, _, ()>("]")(v.data()) {
1066855e09eSopenharmony_ci            Ok((i, _)) => {
1076855e09eSopenharmony_ci              println!("]");
1086855e09eSopenharmony_ci              v.offset(i);
1096855e09eSopenharmony_ci              done = true;
1106855e09eSopenharmony_ci              return None;
1116855e09eSopenharmony_ci            }
1126855e09eSopenharmony_ci            Err(_) => {}
1136855e09eSopenharmony_ci          };
1146855e09eSopenharmony_ci
1156855e09eSopenharmony_ci          if first {
1166855e09eSopenharmony_ci            first = false;
1176855e09eSopenharmony_ci          } else {
1186855e09eSopenharmony_ci            match tag::<_, _, ()>(",")(v.data()) {
1196855e09eSopenharmony_ci              Ok((i, _)) => {
1206855e09eSopenharmony_ci                println!(",");
1216855e09eSopenharmony_ci                v.offset(i);
1226855e09eSopenharmony_ci              }
1236855e09eSopenharmony_ci              Err(_) => {
1246855e09eSopenharmony_ci                done = true;
1256855e09eSopenharmony_ci                return None;
1266855e09eSopenharmony_ci              }
1276855e09eSopenharmony_ci            }
1286855e09eSopenharmony_ci          }
1296855e09eSopenharmony_ci
1306855e09eSopenharmony_ci          println!("-> {}", v.data());
1316855e09eSopenharmony_ci          previous = v.offset.get();
1326855e09eSopenharmony_ci          Some(v.clone())
1336855e09eSopenharmony_ci        }))
1346855e09eSopenharmony_ci      }
1356855e09eSopenharmony_ci    }
1366855e09eSopenharmony_ci  }
1376855e09eSopenharmony_ci
1386855e09eSopenharmony_ci  pub fn object(&self) -> Option<impl Iterator<Item = (&'a str, JsonValue<'a, 'b>)>> {
1396855e09eSopenharmony_ci    println!("object()");
1406855e09eSopenharmony_ci    match tag::<_, _, ()>("{")(self.data()) {
1416855e09eSopenharmony_ci      Err(_) => None,
1426855e09eSopenharmony_ci      Ok((i, _)) => {
1436855e09eSopenharmony_ci        self.offset(i);
1446855e09eSopenharmony_ci
1456855e09eSopenharmony_ci        println!("{{");
1466855e09eSopenharmony_ci
1476855e09eSopenharmony_ci        let mut first = true;
1486855e09eSopenharmony_ci        let mut done = false;
1496855e09eSopenharmony_ci        let mut previous = std::usize::MAX;
1506855e09eSopenharmony_ci
1516855e09eSopenharmony_ci        let v = self.clone();
1526855e09eSopenharmony_ci
1536855e09eSopenharmony_ci        Some(std::iter::from_fn(move || {
1546855e09eSopenharmony_ci          if done {
1556855e09eSopenharmony_ci            return None;
1566855e09eSopenharmony_ci          }
1576855e09eSopenharmony_ci
1586855e09eSopenharmony_ci          // if we ignored one of the items, skip over the value
1596855e09eSopenharmony_ci          if v.offset.get() == previous {
1606855e09eSopenharmony_ci            println!("skipping value");
1616855e09eSopenharmony_ci            match value(v.data()) {
1626855e09eSopenharmony_ci              Ok((i, _)) => {
1636855e09eSopenharmony_ci                v.offset(i);
1646855e09eSopenharmony_ci              }
1656855e09eSopenharmony_ci              Err(_) => {}
1666855e09eSopenharmony_ci            }
1676855e09eSopenharmony_ci          }
1686855e09eSopenharmony_ci
1696855e09eSopenharmony_ci          match tag::<_, _, ()>("}")(v.data()) {
1706855e09eSopenharmony_ci            Ok((i, _)) => {
1716855e09eSopenharmony_ci              println!("}}");
1726855e09eSopenharmony_ci              v.offset(i);
1736855e09eSopenharmony_ci              done = true;
1746855e09eSopenharmony_ci              return None;
1756855e09eSopenharmony_ci            }
1766855e09eSopenharmony_ci            Err(_) => {}
1776855e09eSopenharmony_ci          };
1786855e09eSopenharmony_ci
1796855e09eSopenharmony_ci          if first {
1806855e09eSopenharmony_ci            first = false;
1816855e09eSopenharmony_ci          } else {
1826855e09eSopenharmony_ci            match tag::<_, _, ()>(",")(v.data()) {
1836855e09eSopenharmony_ci              Ok((i, _)) => {
1846855e09eSopenharmony_ci                println!(",");
1856855e09eSopenharmony_ci                v.offset(i);
1866855e09eSopenharmony_ci              }
1876855e09eSopenharmony_ci              Err(_) => {
1886855e09eSopenharmony_ci                done = true;
1896855e09eSopenharmony_ci                return None;
1906855e09eSopenharmony_ci              }
1916855e09eSopenharmony_ci            }
1926855e09eSopenharmony_ci          }
1936855e09eSopenharmony_ci
1946855e09eSopenharmony_ci          match string(v.data()) {
1956855e09eSopenharmony_ci            Ok((i, key)) => {
1966855e09eSopenharmony_ci              v.offset(i);
1976855e09eSopenharmony_ci
1986855e09eSopenharmony_ci              match tag::<_, _, ()>(":")(v.data()) {
1996855e09eSopenharmony_ci                Err(_) => None,
2006855e09eSopenharmony_ci                Ok((i, _)) => {
2016855e09eSopenharmony_ci                  v.offset(i);
2026855e09eSopenharmony_ci
2036855e09eSopenharmony_ci                  previous = v.offset.get();
2046855e09eSopenharmony_ci
2056855e09eSopenharmony_ci                  println!("-> {} => {}", key, v.data());
2066855e09eSopenharmony_ci                  Some((key, v.clone()))
2076855e09eSopenharmony_ci                }
2086855e09eSopenharmony_ci              }
2096855e09eSopenharmony_ci            }
2106855e09eSopenharmony_ci            _ => None,
2116855e09eSopenharmony_ci          }
2126855e09eSopenharmony_ci        }))
2136855e09eSopenharmony_ci      }
2146855e09eSopenharmony_ci    }
2156855e09eSopenharmony_ci  }
2166855e09eSopenharmony_ci}
2176855e09eSopenharmony_ci
2186855e09eSopenharmony_cifn sp<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, &'a str, E> {
2196855e09eSopenharmony_ci  let chars = " \t\r\n";
2206855e09eSopenharmony_ci
2216855e09eSopenharmony_ci  take_while(move |c| chars.contains(c))(i)
2226855e09eSopenharmony_ci}
2236855e09eSopenharmony_ci
2246855e09eSopenharmony_cifn parse_str<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, &'a str, E> {
2256855e09eSopenharmony_ci  escaped(alphanumeric, '\\', one_of("\"n\\"))(i)
2266855e09eSopenharmony_ci}
2276855e09eSopenharmony_ci
2286855e09eSopenharmony_cifn string<'a>(i: &'a str) -> IResult<&'a str, &'a str> {
2296855e09eSopenharmony_ci  context(
2306855e09eSopenharmony_ci    "string",
2316855e09eSopenharmony_ci    preceded(char('\"'), cut(terminated(parse_str, char('\"')))),
2326855e09eSopenharmony_ci  )(i)
2336855e09eSopenharmony_ci}
2346855e09eSopenharmony_ci
2356855e09eSopenharmony_cifn boolean<'a>(input: &'a str) -> IResult<&'a str, bool> {
2366855e09eSopenharmony_ci  alt((map(tag("false"), |_| false), map(tag("true"), |_| true)))(input)
2376855e09eSopenharmony_ci}
2386855e09eSopenharmony_ci
2396855e09eSopenharmony_cifn array<'a>(i: &'a str) -> IResult<&'a str, ()> {
2406855e09eSopenharmony_ci  context(
2416855e09eSopenharmony_ci    "array",
2426855e09eSopenharmony_ci    preceded(
2436855e09eSopenharmony_ci      char('['),
2446855e09eSopenharmony_ci      cut(terminated(
2456855e09eSopenharmony_ci        map(separated_list0(preceded(sp, char(',')), value), |_| ()),
2466855e09eSopenharmony_ci        preceded(sp, char(']')),
2476855e09eSopenharmony_ci      )),
2486855e09eSopenharmony_ci    ),
2496855e09eSopenharmony_ci  )(i)
2506855e09eSopenharmony_ci}
2516855e09eSopenharmony_ci
2526855e09eSopenharmony_cifn key_value<'a>(i: &'a str) -> IResult<&'a str, (&'a str, ())> {
2536855e09eSopenharmony_ci  separated_pair(preceded(sp, string), cut(preceded(sp, char(':'))), value)(i)
2546855e09eSopenharmony_ci}
2556855e09eSopenharmony_ci
2566855e09eSopenharmony_cifn hash<'a>(i: &'a str) -> IResult<&'a str, ()> {
2576855e09eSopenharmony_ci  context(
2586855e09eSopenharmony_ci    "map",
2596855e09eSopenharmony_ci    preceded(
2606855e09eSopenharmony_ci      char('{'),
2616855e09eSopenharmony_ci      cut(terminated(
2626855e09eSopenharmony_ci        map(separated_list0(preceded(sp, char(',')), key_value), |_| ()),
2636855e09eSopenharmony_ci        preceded(sp, char('}')),
2646855e09eSopenharmony_ci      )),
2656855e09eSopenharmony_ci    ),
2666855e09eSopenharmony_ci  )(i)
2676855e09eSopenharmony_ci}
2686855e09eSopenharmony_ci
2696855e09eSopenharmony_cifn value<'a>(i: &'a str) -> IResult<&'a str, ()> {
2706855e09eSopenharmony_ci  preceded(
2716855e09eSopenharmony_ci    sp,
2726855e09eSopenharmony_ci    alt((
2736855e09eSopenharmony_ci      hash,
2746855e09eSopenharmony_ci      array,
2756855e09eSopenharmony_ci      map(string, |_| ()),
2766855e09eSopenharmony_ci      map(double, |_| ()),
2776855e09eSopenharmony_ci      map(boolean, |_| ()),
2786855e09eSopenharmony_ci    )),
2796855e09eSopenharmony_ci  )(i)
2806855e09eSopenharmony_ci}
2816855e09eSopenharmony_ci
2826855e09eSopenharmony_ci/// object(input) -> iterator over (key, JsonValue)
2836855e09eSopenharmony_ci/// array(input) -> iterator over JsonValue
2846855e09eSopenharmony_ci///
2856855e09eSopenharmony_ci/// JsonValue.string -> iterator over String (returns None after first successful call)
2866855e09eSopenharmony_ci///
2876855e09eSopenharmony_ci/// object(input).filter(|(k, _)| k == "users").flatten(|(_, v)| v.object()).filter(|(k, _)| k == "city").flatten(|(_,v)| v.string())
2886855e09eSopenharmony_cifn main() {
2896855e09eSopenharmony_ci  /*let data = "{
2906855e09eSopenharmony_ci  \"users\": {
2916855e09eSopenharmony_ci    \"user1\" : { \"city\": \"Nantes\", \"country\": \"France\" },
2926855e09eSopenharmony_ci    \"user2\" : { \"city\": \"Bruxelles\", \"country\": \"Belgium\" },
2936855e09eSopenharmony_ci    \"user3\": { \"city\": \"Paris\", \"country\": \"France\", \"age\": 30 }
2946855e09eSopenharmony_ci  },
2956855e09eSopenharmony_ci  \"countries\": [\"France\", \"Belgium\"]
2966855e09eSopenharmony_ci  }";
2976855e09eSopenharmony_ci  */
2986855e09eSopenharmony_ci  let data = "{\"users\":{\"user1\":{\"city\":\"Nantes\",\"country\":\"France\"},\"user2\":{\"city\":\"Bruxelles\",\"country\":\"Belgium\"},\"user3\":{\"city\":\"Paris\",\"country\":\"France\",\"age\":30}},\"countries\":[\"France\",\"Belgium\"]}";
2996855e09eSopenharmony_ci
3006855e09eSopenharmony_ci  let offset = Cell::new(0);
3016855e09eSopenharmony_ci  {
3026855e09eSopenharmony_ci    let parser = JsonValue::new(data, &offset);
3036855e09eSopenharmony_ci
3046855e09eSopenharmony_ci    if let Some(o) = parser.object() {
3056855e09eSopenharmony_ci      let s: HashMap<&str, &str> = o
3066855e09eSopenharmony_ci        .filter(|(k, _)| *k == "users")
3076855e09eSopenharmony_ci        .filter_map(|(_, v)| v.object())
3086855e09eSopenharmony_ci        .flatten()
3096855e09eSopenharmony_ci        .filter_map(|(user, v)| v.object().map(|o| (user, o)))
3106855e09eSopenharmony_ci        .map(|(user, o)| {
3116855e09eSopenharmony_ci          o.filter(|(k, _)| *k == "city")
3126855e09eSopenharmony_ci            .filter_map(move |(_, v)| v.string().map(|s| (user, s)))
3136855e09eSopenharmony_ci        })
3146855e09eSopenharmony_ci        .flatten()
3156855e09eSopenharmony_ci        .collect();
3166855e09eSopenharmony_ci
3176855e09eSopenharmony_ci      println!("res = {:?}", s);
3186855e09eSopenharmony_ci    }
3196855e09eSopenharmony_ci  };
3206855e09eSopenharmony_ci}
321