surrealdb_core/syn/parser/
json.rs

1use 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}