ephemeris_documents/json/
backend.rs1use super::Dialect;
4use super::cst::{Document, Kind, Value};
5use super::lexer::{Lexer, TokenKind};
6use crate::annotation::Annotated;
7use crate::backend::{Backend, Editable as _};
8use crate::error::{DocumentError, JsonError, JsonErrorKind};
9use crate::format::Format;
10use crate::header::Existing;
11
12#[derive(Debug, Clone, Copy)]
14pub(crate) struct Json {
15 dialect: Dialect,
16}
17
18impl Json {
19 pub(crate) const fn new(dialect: Dialect) -> Self {
20 Self { dialect }
21 }
22}
23
24impl Backend for Json {
25 type Document = Document;
26
27 fn parse(&self, source: &str) -> Result<Document, DocumentError> {
28 Ok(Document::parse(source, self.dialect)?)
29 }
30
31 fn build(&self, desired: &Annotated) -> Result<Document, DocumentError> {
32 Ok(Document::build(desired, self.dialect))
33 }
34
35 fn format(&self) -> Format {
36 self.dialect.format()
37 }
38
39 fn string_leaf(&self, node: &Value) -> Result<Option<String>, DocumentError> {
40 let Kind::Scalar(scalar) = &node.kind else {
41 return Ok(None);
42 };
43 let tokens = Lexer::tokenize(scalar.text())?;
44 match tokens.into_iter().next().map(|token| token.kind) {
45 Some(TokenKind::String(Some(text))) => Ok(Some(text)),
46 Some(TokenKind::String(None)) => Err(JsonError {
47 offset: scalar.offset(),
48 kind: JsonErrorKind::InvalidEscape,
49 }
50 .into()),
51 _ => Ok(None),
52 }
53 }
54
55 fn finish(&self, current: &mut Document, desired: &Document, existing: Existing) {
56 current.apply_header(desired, existing);
57 current.end_with_newline();
58 }
59}