ephemeris_documents/json/cst/
key.rs1use std::borrow::Cow;
4
5use super::quote::Quote;
6use crate::json::Dialect;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
11pub(crate) struct Key {
12 source: Option<String>,
13 name: String,
14}
15
16impl Key {
17 pub(in crate::json) const fn from_source(source: String, name: String) -> Self {
18 Self {
19 source: Some(source),
20 name,
21 }
22 }
23
24 pub(super) fn canonical(name: &str) -> Self {
26 Self {
27 source: None,
28 name: name.to_owned(),
29 }
30 }
31
32 pub(in crate::json) fn name(&self) -> &str {
33 &self.name
34 }
35
36 fn is_plain_identifier(name: &str) -> bool {
37 let mut chars = name.chars();
38 match chars.next() {
39 Some(first) if first.is_ascii_alphabetic() || first == '_' || first == '$' => {}
40 _ => return false,
41 }
42 chars.all(|character| {
43 character.is_ascii_alphanumeric() || character == '_' || character == '$'
44 })
45 }
46
47 pub(super) fn spelling(&self, dialect: Dialect) -> Cow<'_, str> {
49 match &self.source {
50 Some(source) => Cow::Borrowed(source),
51 None if dialect == Dialect::Json5 && Self::is_plain_identifier(&self.name) => {
52 Cow::Borrowed(&self.name)
53 }
54 None => Cow::Owned(Quote::Double.wrap(&self.name)),
55 }
56 }
57}