surrealdb_core/syn/parser/
json.rs1use std::collections::BTreeMap;
2
3use reblessive::Stk;
4
5use crate::{
6 sql::{Array, Duration, Ident, Object, Strand, Value},
7 syn::{
8 lexer::compound::{self, Numeric},
9 parser::mac::{expected, pop_glued},
10 token::{t, Glued, Span, TokenKind},
11 },
12};
13
14use super::{ParseResult, Parser};
15
16impl Parser<'_> {
17 pub async fn parse_json(&mut self, ctx: &mut Stk) -> ParseResult<Value> {
18 let token = self.peek();
19 match token.kind {
20 t!("NULL") => {
21 self.pop_peek();
22 Ok(Value::Null)
23 }
24 t!("true") => {
25 self.pop_peek();
26 Ok(Value::Bool(true))
27 }
28 t!("false") => {
29 self.pop_peek();
30 Ok(Value::Bool(false))
31 }
32 t!("{") => {
33 self.pop_peek();
34 self.parse_json_object(ctx, token.span).await.map(Value::Object)
35 }
36 t!("[") => {
37 self.pop_peek();
38 self.parse_json_array(ctx, token.span).await.map(Value::Array)
39 }
40 t!("\"") | t!("'") => {
41 let strand: Strand = self.next_token_value()?;
42 if self.settings.legacy_strands {
43 if let Some(x) = self.reparse_legacy_strand(ctx, &strand.0).await {
44 return Ok(x);
45 }
46 }
47 Ok(Value::Strand(strand))
48 }
49 t!("-") | t!("+") | TokenKind::Digits => {
50 self.pop_peek();
51 let compound = self.lexer.lex_compound(token, compound::numeric)?;
52 match compound.value {
53 Numeric::Duration(x) => Ok(Value::Duration(Duration(x))),
54 Numeric::Number(x) => Ok(Value::Number(x)),
55 }
56 }
57 TokenKind::Glued(Glued::Strand) => {
58 let glued = pop_glued!(self, Strand);
59 Ok(Value::Strand(glued))
60 }
61 TokenKind::Glued(Glued::Duration) => {
62 let glued = pop_glued!(self, Duration);
63 Ok(Value::Duration(glued))
64 }
65 _ => {
66 let ident = self.next_token_value::<Ident>()?.0;
67 self.parse_thing_from_ident(ctx, ident).await.map(Value::Thing)
68 }
69 }
70 }
71
72 async fn parse_json_object(&mut self, ctx: &mut Stk, start: Span) -> ParseResult<Object> {
73 let mut obj = BTreeMap::new();
74 loop {
75 if self.eat(t!("}")) {
76 return Ok(Object(obj));
77 }
78 let key = self.parse_object_key()?;
79 expected!(self, t!(":"));
80 let value = ctx.run(|ctx| self.parse_json(ctx)).await?;
81 obj.insert(key, value);
82
83 if !self.eat(t!(",")) {
84 self.expect_closing_delimiter(t!("}"), start)?;
85 return Ok(Object(obj));
86 }
87 }
88 }
89
90 async fn parse_json_array(&mut self, ctx: &mut Stk, start: Span) -> ParseResult<Array> {
91 let mut array = Vec::new();
92 loop {
93 if self.eat(t!("]")) {
94 return Ok(Array(array));
95 }
96 let value = ctx.run(|ctx| self.parse_json(ctx)).await?;
97 array.push(value);
98
99 if !self.eat(t!(",")) {
100 self.expect_closing_delimiter(t!("]"), start)?;
101 return Ok(Array(array));
102 }
103 }
104 }
105}