1#![doc = include_str!("readme.md")]
2use core::range::Range;
3use oak_core::source::{SourceBuffer, ToSource};
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6
7#[cfg(feature = "oak-pretty-print")]
8use oak_pretty_print::{AsDocument, doc as pp_doc};
9
10#[derive(Clone, Debug, PartialEq)]
12#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
13#[cfg_attr(feature = "oak-pretty-print", derive(AsDocument))]
14pub struct JsonRoot {
15 pub value: JsonValue,
17}
18
19impl ToSource for JsonRoot {
20 fn to_source(&self, buffer: &mut SourceBuffer) {
21 self.value.to_source(buffer)
22 }
23}
24
25#[derive(Clone, Debug, PartialEq)]
27#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
28#[cfg_attr(feature = "oak-pretty-print", derive(AsDocument))]
29pub enum JsonValue {
30 Object(JsonObject),
32 Array(JsonArray),
34 String(JsonString),
36 Number(JsonNumber),
38 Boolean(JsonBoolean),
40 Null(JsonNull),
42}
43
44impl JsonValue {
45 pub fn as_str(&self) -> Option<&str> {
46 match self {
47 JsonValue::String(s) => Some(&s.value),
48 _ => None,
49 }
50 }
51
52 pub fn as_f64(&self) -> Option<f64> {
53 match self {
54 JsonValue::Number(n) => Some(n.value),
55 _ => None,
56 }
57 }
58
59 pub fn as_bool(&self) -> Option<bool> {
60 match self {
61 JsonValue::Boolean(b) => Some(b.value),
62 _ => None,
63 }
64 }
65
66 pub fn as_u64(&self) -> Option<u64> {
67 self.as_f64().map(|f| f as u64)
68 }
69
70 pub fn as_array(&self) -> Option<&JsonArray> {
71 match self {
72 JsonValue::Array(a) => Some(a),
73 _ => None,
74 }
75 }
76
77 pub fn as_object(&self) -> Option<&JsonObject> {
78 match self {
79 JsonValue::Object(o) => Some(o),
80 _ => None,
81 }
82 }
83
84 pub fn get(&self, key: &str) -> Option<&JsonValue> {
85 match self {
86 JsonValue::Object(o) => o.get(key),
87 _ => None,
88 }
89 }
90
91 pub fn to_string(&self) -> String {
92 match self {
93 JsonValue::Null(_) => "null".to_string(),
94 JsonValue::Boolean(b) => b.value.to_string(),
95 JsonValue::Number(n) => n.value.to_string(),
96 JsonValue::String(s) => format!("\"{}\"", s.value),
97 JsonValue::Array(a) => {
98 let elements: Vec<String> = a.elements.iter().map(|e| e.to_string()).collect();
99 format!("[{}]", elements.join(","))
100 }
101 JsonValue::Object(o) => {
102 let fields: Vec<String> = o.fields.iter().map(|f| format!("\"{}\":{}", f.name.value, f.value.to_string())).collect();
103 format!("{{{}}}", fields.join(","))
104 }
105 }
106 }
107}
108
109impl std::fmt::Display for JsonValue {
110 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111 write!(f, "{}", self.to_string())
112 }
113}
114
115impl From<&str> for JsonValue {
116 fn from(s: &str) -> Self {
117 JsonValue::String(JsonString { value: s.to_string(), span: (0..0).into() })
118 }
119}
120
121impl From<String> for JsonValue {
122 fn from(s: String) -> Self {
123 JsonValue::String(JsonString { value: s, span: (0..0).into() })
124 }
125}
126
127impl From<f64> for JsonValue {
128 fn from(f: f64) -> Self {
129 JsonValue::Number(JsonNumber { value: f, span: (0..0).into() })
130 }
131}
132
133impl From<u64> for JsonValue {
134 fn from(u: u64) -> Self {
135 JsonValue::Number(JsonNumber { value: u as f64, span: (0..0).into() })
136 }
137}
138
139impl From<i32> for JsonValue {
140 fn from(i: i32) -> Self {
141 JsonValue::Number(JsonNumber { value: i as f64, span: (0..0).into() })
142 }
143}
144
145impl From<i64> for JsonValue {
146 fn from(i: i64) -> Self {
147 JsonValue::Number(JsonNumber { value: i as f64, span: (0..0).into() })
148 }
149}
150
151impl From<usize> for JsonValue {
152 fn from(u: usize) -> Self {
153 JsonValue::Number(JsonNumber { value: u as f64, span: (0..0).into() })
154 }
155}
156
157impl From<bool> for JsonValue {
158 fn from(b: bool) -> Self {
159 JsonValue::Boolean(JsonBoolean { value: b, span: (0..0).into() })
160 }
161}
162
163impl From<u32> for JsonValue {
164 fn from(value: u32) -> Self {
165 JsonValue::Number(JsonNumber { value: value as f64, span: (0..0).into() })
166 }
167}
168
169impl From<f32> for JsonValue {
170 fn from(value: f32) -> Self {
171 JsonValue::Number(JsonNumber { value: value as f64, span: (0..0).into() })
172 }
173}
174
175impl<T: Into<JsonValue>> From<Option<T>> for JsonValue {
176 fn from(value: Option<T>) -> Self {
177 match value {
178 Some(v) => v.into(),
179 None => JsonValue::Null(JsonNull { span: (0..0).into() }),
180 }
181 }
182}
183
184impl From<()> for JsonValue {
185 fn from(_: ()) -> Self {
186 JsonValue::Null(JsonNull { span: (0..0).into() })
187 }
188}
189
190impl From<[JsonValue; 0]> for JsonValue {
191 fn from(_: [JsonValue; 0]) -> Self {
192 JsonValue::Array(JsonArray { elements: vec![], span: (0..0).into() })
193 }
194}
195
196impl From<Vec<JsonValue>> for JsonValue {
197 fn from(elements: Vec<JsonValue>) -> Self {
198 JsonValue::Array(JsonArray { elements, span: (0..0).into() })
199 }
200}
201
202impl From<std::collections::HashMap<String, JsonValue>> for JsonValue {
203 fn from(fields: std::collections::HashMap<String, JsonValue>) -> Self {
204 let mut fields_vec: Vec<JsonField> = fields.into_iter().map(|(k, v)| JsonField { name: JsonString { value: k, span: (0..0).into() }, value: v, span: (0..0).into() }).collect();
205 fields_vec.sort_by(|a, b| a.name.value.cmp(&b.name.value));
207 JsonValue::Object(JsonObject { fields: fields_vec, span: (0..0).into() })
208 }
209}
210
211impl<T: Into<JsonValue>> FromIterator<T> for JsonValue {
212 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
213 JsonValue::Array(JsonArray { elements: iter.into_iter().map(Into::into).collect(), span: (0..0).into() })
214 }
215}
216
217impl ToSource for JsonValue {
218 fn to_source(&self, buffer: &mut SourceBuffer) {
219 match self {
220 JsonValue::Object(v) => v.to_source(buffer),
221 JsonValue::Array(v) => v.to_source(buffer),
222 JsonValue::String(v) => v.to_source(buffer),
223 JsonValue::Number(v) => v.to_source(buffer),
224 JsonValue::Boolean(v) => v.to_source(buffer),
225 JsonValue::Null(v) => v.to_source(buffer),
226 }
227 }
228}
229
230#[derive(Clone, Debug, PartialEq)]
232#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
233#[cfg_attr(feature = "oak-pretty-print", derive(AsDocument))]
234#[cfg_attr(feature = "oak-pretty-print", oak(doc =
235 if _self.fields.is_empty() {
236 pp_doc!("{}")
237 } else {
238 pp_doc!(group( [
239 "{",
240 indent( [line, join(_self.fields.iter(), [",", line])]),
241 line,
242 "}"
243 ]))
244 }
245))]
246pub struct JsonObject {
247 pub fields: Vec<JsonField>,
249 #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
251 pub span: Range<usize>,
252}
253
254impl JsonObject {
255 pub fn get(&self, key: &str) -> Option<&JsonValue> {
257 self.fields.iter().find(|f| f.name.value == key).map(|f| &f.value)
258 }
259}
260
261impl ToSource for JsonObject {
262 fn to_source(&self, buffer: &mut SourceBuffer) {
263 buffer.push("{");
264 for (i, field) in self.fields.iter().enumerate() {
265 if i > 0 {
266 buffer.push(",")
267 }
268 field.to_source(buffer)
269 }
270 buffer.push("}")
271 }
272}
273
274#[derive(Clone, Debug, PartialEq)]
276#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
277#[cfg_attr(feature = "oak-pretty-print", derive(AsDocument))]
278#[cfg_attr(feature = "oak-pretty-print", oak(doc = [self.name.as_document(), ": ", self.value.as_document()]))]
279pub struct JsonField {
280 pub name: JsonString,
282 pub value: JsonValue,
284 #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
286 pub span: Range<usize>,
287}
288
289impl ToSource for JsonField {
290 fn to_source(&self, buffer: &mut SourceBuffer) {
291 self.name.to_source(buffer);
292 buffer.push(":");
293 self.value.to_source(buffer)
294 }
295}
296
297#[derive(Clone, Debug, PartialEq)]
299#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
300#[cfg_attr(feature = "oak-pretty-print", derive(AsDocument))]
301#[cfg_attr(feature = "oak-pretty-print", oak(doc =
302 if _self.elements.is_empty() {
303 pp_doc!("[]")
304 } else {
305 pp_doc!(group( [
306 "[",
307 indent( [line, join(_self.elements.iter(), [",", line])]),
308 line,
309 "]"
310 ]))
311 }
312))]
313pub struct JsonArray {
314 pub elements: Vec<JsonValue>,
316 #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
318 pub span: Range<usize>,
319}
320
321impl ToSource for JsonArray {
322 fn to_source(&self, buffer: &mut SourceBuffer) {
323 buffer.push("[");
324 for (i, element) in self.elements.iter().enumerate() {
325 if i > 0 {
326 buffer.push(",")
327 }
328 element.to_source(buffer)
329 }
330 buffer.push("]")
331 }
332}
333
334#[derive(Clone, Debug, PartialEq)]
336#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
337#[cfg_attr(feature = "oak-pretty-print", derive(AsDocument))]
338#[cfg_attr(feature = "oak-pretty-print", oak(doc = format!("\"{}\"", self.value)))]
339pub struct JsonString {
340 pub value: String,
342 #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
344 pub span: Range<usize>,
345}
346
347impl ToSource for JsonString {
348 fn to_source(&self, buffer: &mut SourceBuffer) {
349 buffer.push("\"");
350 buffer.push(&self.value);
351 buffer.push("\"")
352 }
353}
354
355#[derive(Clone, Debug, PartialEq)]
357#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
358#[cfg_attr(feature = "oak-pretty-print", derive(AsDocument))]
359#[cfg_attr(feature = "oak-pretty-print", oak(doc = self.value.to_string()))]
360pub struct JsonNumber {
361 pub value: f64,
363 #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
365 pub span: Range<usize>,
366}
367
368impl ToSource for JsonNumber {
369 fn to_source(&self, buffer: &mut SourceBuffer) {
370 buffer.push(&self.value.to_string())
371 }
372}
373
374#[derive(Clone, Debug, PartialEq)]
376#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
377#[cfg_attr(feature = "oak-pretty-print", derive(AsDocument))]
378#[cfg_attr(feature = "oak-pretty-print", oak(doc = if self.value { "true" } else { "false" }))]
379pub struct JsonBoolean {
380 pub value: bool,
382 #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
384 pub span: Range<usize>,
385}
386
387impl ToSource for JsonBoolean {
388 fn to_source(&self, buffer: &mut SourceBuffer) {
389 buffer.push(if self.value { "true" } else { "false" })
390 }
391}
392
393#[derive(Clone, Debug, PartialEq)]
395#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
396#[cfg_attr(feature = "oak-pretty-print", derive(AsDocument))]
397#[cfg_attr(feature = "oak-pretty-print", oak(doc = "null"))]
398pub struct JsonNull {
399 #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
401 pub span: Range<usize>,
402}
403
404impl ToSource for JsonNull {
405 fn to_source(&self, buffer: &mut SourceBuffer) {
406 buffer.push("null")
407 }
408}