1use alloc::string::String;
7use alloc::vec::Vec;
8use core::fmt;
9use azul_css::{
10 AzString, OptionString, OptionF64, OptionBool,
11 impl_vec, impl_vec_clone, impl_vec_debug, impl_vec_partialeq, impl_vec_mut,
12 impl_result, impl_result_inner,
13 impl_option, impl_option_inner,
14};
15
16#[derive(Debug, Clone, PartialEq)]
22#[repr(C)]
23pub struct Json {
24 pub value_type: JsonType,
26 pub internal: JsonInternal,
29}
30
31#[derive(Debug, Clone, PartialEq)]
39#[repr(C)]
40pub struct JsonInternal {
41 pub string_value: AzString,
43 pub number_value: f64,
45 pub bool_value: bool,
47}
48
49impl Default for JsonInternal {
50 fn default() -> Self {
51 Self {
52 string_value: AzString::from(String::new()),
53 number_value: 0.0,
54 bool_value: false,
55 }
56 }
57}
58
59#[derive(Debug, Clone, Copy, PartialEq, Eq)]
61#[repr(C)]
62pub enum JsonType {
63 Null,
65 Bool,
67 Number,
69 String,
71 Array,
73 Object,
75}
76
77#[derive(Debug, Clone, PartialEq)]
79#[repr(C)]
80pub struct JsonParseError {
81 pub message: AzString,
83 pub line: u32,
85 pub column: u32,
87}
88
89impl fmt::Display for JsonParseError {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 if self.line > 0 {
92 write!(f, "{}:{}: {}", self.line, self.column, self.message.as_str())
93 } else {
94 write!(f, "{}", self.message.as_str())
95 }
96 }
97}
98
99#[cfg(feature = "std")]
100impl std::error::Error for JsonParseError {}
101
102#[derive(Debug, Clone, PartialEq)]
104#[repr(C)]
105pub struct JsonKeyValue {
106 pub key: AzString,
108 pub value: Json,
110}
111
112impl JsonKeyValue {
113 pub fn create(key: AzString, value: Json) -> Self {
115 Self { key, value }
116 }
117}
118
119impl_option!(JsonKeyValue, OptionJsonKeyValue, copy = false, [Debug, Clone, PartialEq]);
125
126impl_vec!(JsonKeyValue, JsonKeyValueVec, JsonKeyValueVecDestructor, JsonKeyValueVecDestructorType, JsonKeyValueVecSlice, OptionJsonKeyValue);
128impl_vec_clone!(JsonKeyValue, JsonKeyValueVec, JsonKeyValueVecDestructor);
129impl_vec_debug!(JsonKeyValue, JsonKeyValueVec);
130
131impl JsonKeyValueVec {
132 #[inline]
134 pub fn copy_from_array(ptr: *const JsonKeyValue, len: usize) -> Self {
135 if ptr.is_null() || len == 0 {
136 return Self::new();
137 }
138 let slice = unsafe { core::slice::from_raw_parts(ptr, len) };
139 Self::from_vec(slice.iter().cloned().collect())
140 }
141}
142
143impl_vec!(Json, JsonVec, JsonVecDestructor, JsonVecDestructorType, JsonVecSlice, OptionJson);
145impl_vec_clone!(Json, JsonVec, JsonVecDestructor);
146impl_vec_debug!(Json, JsonVec);
147impl_vec_partialeq!(Json, JsonVec);
148impl_vec_mut!(Json, JsonVec);
149
150impl JsonVec {
151 #[inline]
153 pub fn copy_from_array(ptr: *const Json, len: usize) -> Self {
154 if ptr.is_null() || len == 0 {
155 return Self::new();
156 }
157 let slice = unsafe { core::slice::from_raw_parts(ptr, len) };
158 Self::from_vec(slice.iter().cloned().collect())
159 }
160}
161
162impl_result!(
164 Json,
165 JsonParseError,
166 ResultJsonJsonParseError,
167 copy = false,
168 [Debug, Clone, PartialEq]
169);
170
171impl_option!(Json, OptionJson, copy = false, [Clone, Debug, PartialEq]);
173impl_option!(JsonVec, OptionJsonVec, copy = false, [Clone, Debug]);
174impl_option!(JsonKeyValueVec, OptionJsonKeyValueVec, copy = false, [Clone, Debug]);
175
176impl_option!(i64, OptionI64, [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]);
179
180fn f64_as_i64(n: f64) -> Option<i64> {
191 if n.fract() == 0.0 && n >= -(2_f64.powi(63)) && n < 2_f64.powi(63) {
192 Some(n as i64)
193 } else {
194 None
195 }
196}
197
198impl Json {
203 pub fn null() -> Self {
205 Self {
206 value_type: JsonType::Null,
207 internal: JsonInternal::default(),
208 }
209 }
210
211 pub fn bool(value: bool) -> Self {
213 Self {
214 value_type: JsonType::Bool,
215 internal: JsonInternal {
216 string_value: AzString::from(String::new()),
217 number_value: 0.0,
218 bool_value: value,
219 },
220 }
221 }
222
223 pub fn number(value: f64) -> Self {
225 Self {
226 value_type: JsonType::Number,
227 internal: JsonInternal {
228 string_value: AzString::from(String::new()),
229 number_value: value,
230 bool_value: false,
231 },
232 }
233 }
234
235 pub fn integer(value: i64) -> Self {
240 Self {
241 value_type: JsonType::Number,
242 internal: JsonInternal {
243 string_value: AzString::from(String::new()),
244 number_value: value as f64,
245 bool_value: false,
246 },
247 }
248 }
249
250 pub fn string(value: impl Into<String>) -> Self {
252 Self {
253 value_type: JsonType::String,
254 internal: JsonInternal {
255 string_value: AzString::from(value.into()),
256 number_value: 0.0,
257 bool_value: false,
258 },
259 }
260 }
261
262 pub fn is_null(&self) -> bool {
264 self.value_type == JsonType::Null
265 }
266
267 pub fn is_bool(&self) -> bool {
269 self.value_type == JsonType::Bool
270 }
271
272 pub fn is_number(&self) -> bool {
274 self.value_type == JsonType::Number
275 }
276
277 pub fn is_string(&self) -> bool {
279 self.value_type == JsonType::String
280 }
281
282 pub fn is_array(&self) -> bool {
284 self.value_type == JsonType::Array
285 }
286
287 pub fn is_object(&self) -> bool {
289 self.value_type == JsonType::Object
290 }
291
292 pub fn as_bool(&self) -> OptionBool {
294 if self.value_type == JsonType::Bool {
295 OptionBool::Some(self.internal.bool_value)
296 } else {
297 OptionBool::None
298 }
299 }
300
301 pub fn as_number(&self) -> OptionF64 {
303 if self.value_type == JsonType::Number {
304 OptionF64::Some(self.internal.number_value)
305 } else {
306 OptionF64::None
307 }
308 }
309
310 pub fn as_i64(&self) -> OptionI64 {
312 if self.value_type == JsonType::Number {
313 match f64_as_i64(self.internal.number_value) {
314 Some(i) => OptionI64::Some(i),
315 None => OptionI64::None,
316 }
317 } else {
318 OptionI64::None
319 }
320 }
321
322 pub fn as_string(&self) -> OptionString {
324 if self.value_type == JsonType::String {
325 OptionString::Some(self.internal.string_value.clone())
326 } else {
327 OptionString::None
328 }
329 }
330
331 pub fn raw_string(&self) -> &str {
333 self.internal.string_value.as_str()
334 }
335}
336
337impl fmt::Display for Json {
342 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
343 match self.value_type {
344 JsonType::Null => write!(f, "null"),
345 JsonType::Bool => write!(f, "{}", self.internal.bool_value),
346 JsonType::Number => {
347 let num = self.internal.number_value;
348 if let Some(i) = f64_as_i64(num) {
349 write!(f, "{}", i)
350 } else {
351 write!(f, "{}", num)
352 }
353 }
354 JsonType::String => write!(f, "\"{}\"", self.internal.string_value.as_str()),
355 JsonType::Array | JsonType::Object => {
356 write!(f, "{}", self.internal.string_value.as_str())
357 }
358 }
359 }
360}
361
362#[cfg(feature = "serde-json")]
367impl Json {
368 pub fn parse(s: &str) -> Result<Self, JsonParseError> {
370 let value: serde_json::Value = serde_json::from_str(s).map_err(|e| {
371 JsonParseError {
372 message: AzString::from(alloc::format!("{}", e)),
373 line: e.line() as u32,
374 column: e.column() as u32,
375 }
376 })?;
377 Ok(Self::from_serde_value(value))
378 }
379
380 pub fn parse_bytes(bytes: &[u8]) -> Result<Self, JsonParseError> {
382 let value: serde_json::Value = serde_json::from_slice(bytes).map_err(|e| {
383 JsonParseError {
384 message: AzString::from(alloc::format!("{}", e)),
385 line: e.line() as u32,
386 column: e.column() as u32,
387 }
388 })?;
389 Ok(Self::from_serde_value(value))
390 }
391
392 pub fn from_serde_value(value: serde_json::Value) -> Self {
394 match value {
395 serde_json::Value::Null => Self::null(),
396 serde_json::Value::Bool(b) => Self::bool(b),
397 serde_json::Value::Number(n) => Self::number(n.as_f64().unwrap_or(0.0)),
398 serde_json::Value::String(s) => Self::string(s),
399 serde_json::Value::Array(arr) => {
400 let json_str = serde_json::to_string(&serde_json::Value::Array(arr)).unwrap_or_default();
401 Self {
402 value_type: JsonType::Array,
403 internal: JsonInternal {
404 string_value: AzString::from(json_str),
405 number_value: 0.0,
406 bool_value: false,
407 },
408 }
409 }
410 serde_json::Value::Object(obj) => {
411 let json_str = serde_json::to_string(&serde_json::Value::Object(obj)).unwrap_or_default();
412 Self {
413 value_type: JsonType::Object,
414 internal: JsonInternal {
415 string_value: AzString::from(json_str),
416 number_value: 0.0,
417 bool_value: false,
418 },
419 }
420 }
421 }
422 }
423
424 pub fn to_serde_value(&self) -> serde_json::Value {
426 match self.value_type {
427 JsonType::Null => serde_json::Value::Null,
428 JsonType::Bool => serde_json::Value::Bool(self.internal.bool_value),
429 JsonType::Number => {
430 let num = self.internal.number_value;
431 if let Some(i) = f64_as_i64(num) {
432 serde_json::Value::Number(serde_json::Number::from(i))
433 } else {
434 serde_json::Number::from_f64(num)
435 .map(serde_json::Value::Number)
436 .unwrap_or(serde_json::Value::Null)
437 }
438 }
439 JsonType::String => serde_json::Value::String(self.internal.string_value.as_str().to_string()),
440 JsonType::Array | JsonType::Object => {
441 serde_json::from_str(self.internal.string_value.as_str())
442 .unwrap_or(serde_json::Value::Null)
443 }
444 }
445 }
446
447 pub fn array(values: JsonVec) -> Self {
449 let serde_array: Vec<serde_json::Value> = values
450 .as_slice()
451 .iter()
452 .map(|j| j.to_serde_value())
453 .collect();
454 let json_str = serde_json::to_string(&serde_json::Value::Array(serde_array))
455 .unwrap_or_else(|_| "[]".to_string());
456 Self {
457 value_type: JsonType::Array,
458 internal: JsonInternal {
459 string_value: AzString::from(json_str),
460 number_value: 0.0,
461 bool_value: false,
462 },
463 }
464 }
465
466 pub fn object(entries: JsonKeyValueVec) -> Self {
468 let mut map = serde_json::Map::new();
469 for kv in entries.as_slice() {
470 map.insert(kv.key.as_str().to_string(), kv.value.to_serde_value());
471 }
472 let json_str = serde_json::to_string(&serde_json::Value::Object(map))
473 .unwrap_or_else(|_| "{}".to_string());
474 Self {
475 value_type: JsonType::Object,
476 internal: JsonInternal {
477 string_value: AzString::from(json_str),
478 number_value: 0.0,
479 bool_value: false,
480 },
481 }
482 }
483
484 pub fn len(&self) -> usize {
486 match self.value_type {
487 JsonType::Array => {
488 if let Ok(serde_json::Value::Array(arr)) = serde_json::from_str(self.internal.string_value.as_str()) {
489 arr.len()
490 } else {
491 0
492 }
493 }
494 JsonType::Object => {
495 if let Ok(serde_json::Value::Object(obj)) = serde_json::from_str(self.internal.string_value.as_str()) {
496 obj.len()
497 } else {
498 0
499 }
500 }
501 _ => 0,
502 }
503 }
504
505 pub fn is_empty(&self) -> bool {
507 self.len() == 0
508 }
509
510 pub fn get_index(&self, index: usize) -> Option<Json> {
512 if self.value_type != JsonType::Array { return None; }
513 let value: serde_json::Value = serde_json::from_str(self.internal.string_value.as_str()).ok()?;
514 if let serde_json::Value::Array(arr) = value {
515 arr.get(index).map(|v| Self::from_serde_value(v.clone()))
516 } else {
517 None
518 }
519 }
520
521 pub fn get_key(&self, key: &str) -> Option<Json> {
523 if self.value_type != JsonType::Object { return None; }
524 let value: serde_json::Value = serde_json::from_str(self.internal.string_value.as_str()).ok()?;
525 if let serde_json::Value::Object(obj) = value {
526 obj.get(key).map(|v| Self::from_serde_value(v.clone()))
527 } else {
528 None
529 }
530 }
531
532 pub fn keys(&self) -> Vec<AzString> {
534 if self.value_type != JsonType::Object { return Vec::new(); }
535 let value: serde_json::Value = match serde_json::from_str(self.internal.string_value.as_str()) {
536 Ok(v) => v,
537 Err(_) => return Vec::new(),
538 };
539 if let serde_json::Value::Object(obj) = value {
540 obj.keys().map(|k| AzString::from(k.clone())).collect()
541 } else {
542 Vec::new()
543 }
544 }
545
546 pub fn to_array(&self) -> Option<JsonVec> {
548 if self.value_type != JsonType::Array { return None; }
549 let value: serde_json::Value = serde_json::from_str(self.internal.string_value.as_str()).ok()?;
550 if let serde_json::Value::Array(arr) = value {
551 Some(arr.into_iter().map(Self::from_serde_value).collect())
552 } else {
553 None
554 }
555 }
556
557 pub fn to_object(&self) -> Option<JsonKeyValueVec> {
559 if self.value_type != JsonType::Object { return None; }
560 let value: serde_json::Value = serde_json::from_str(self.internal.string_value.as_str()).ok()?;
561 if let serde_json::Value::Object(obj) = value {
562 Some(obj.into_iter().map(|(k, v)| JsonKeyValue {
563 key: AzString::from(k),
564 value: Self::from_serde_value(v),
565 }).collect())
566 } else {
567 None
568 }
569 }
570
571 pub fn to_json_string(&self) -> AzString {
573 match self.value_type {
574 JsonType::Null => AzString::from(alloc::string::String::from("null")),
575 JsonType::Bool => AzString::from(if self.internal.bool_value { alloc::string::String::from("true") } else { alloc::string::String::from("false") }),
576 JsonType::Number => {
577 let num = self.internal.number_value;
578 if let Some(i) = f64_as_i64(num) {
579 AzString::from(alloc::format!("{}", i))
580 } else {
581 AzString::from(alloc::format!("{}", num))
582 }
583 }
584 JsonType::String => {
585 let escaped = serde_json::to_string(self.internal.string_value.as_str()).unwrap_or_default();
586 AzString::from(escaped)
587 }
588 JsonType::Array | JsonType::Object => {
589 self.internal.string_value.clone()
590 }
591 }
592 }
593
594 pub fn to_string_pretty(&self) -> AzString {
596 match self.value_type {
597 JsonType::Null | JsonType::Bool | JsonType::Number | JsonType::String => {
598 self.to_json_string()
599 }
600 JsonType::Array | JsonType::Object => {
601 if let Ok(value) = serde_json::from_str::<serde_json::Value>(self.internal.string_value.as_str()) {
602 AzString::from(serde_json::to_string_pretty(&value).unwrap_or_default())
603 } else {
604 self.internal.string_value.clone()
605 }
606 }
607 }
608 }
609
610 pub fn jq(&self, path: &str) -> Json {
612 match self.value_type {
613 JsonType::Null | JsonType::Bool | JsonType::Number | JsonType::String => {
614 if path.is_empty() { self.clone() } else { Json::null() }
615 }
616 JsonType::Array | JsonType::Object => {
617 let value: serde_json::Value = match serde_json::from_str(self.internal.string_value.as_str()) {
618 Ok(v) => v,
619 Err(_) => return Json::null(),
620 };
621 match value.pointer(path) {
622 Some(v) => Self::from_serde_value(v.clone()),
623 None => Json::null(),
624 }
625 }
626 }
627 }
628
629 pub fn jq_all(&self, path: &str) -> JsonVec {
631 let result = match self.value_type {
632 JsonType::Null | JsonType::Bool | JsonType::Number | JsonType::String => {
633 if path.is_empty() { vec![self.clone()] } else { vec![] }
634 }
635 JsonType::Array | JsonType::Object => {
636 let value: serde_json::Value = match serde_json::from_str(self.internal.string_value.as_str()) {
637 Ok(v) => v,
638 Err(_) => return JsonVec::from_vec(vec![]),
639 };
640 Self::jq_all_recursive(&value, path)
641 }
642 };
643 JsonVec::from_vec(result)
644 }
645
646 fn jq_all_recursive(value: &serde_json::Value, path: &str) -> Vec<Json> {
648 if path.is_empty() {
649 return vec![Self::from_serde_value(value.clone())];
650 }
651 if !path.starts_with('/') { return vec![]; }
652 let rest = &path[1..];
653 let (component, remaining) = match rest.find('/') {
654 Some(idx) => (&rest[..idx], &rest[idx..]),
655 None => (rest, ""),
656 };
657 if component == "*" {
658 let mut results = Vec::new();
659 match value {
660 serde_json::Value::Array(arr) => {
661 for item in arr { results.extend(Self::jq_all_recursive(item, remaining)); }
662 }
663 serde_json::Value::Object(obj) => {
664 for (_key, val) in obj { results.extend(Self::jq_all_recursive(val, remaining)); }
665 }
666 _ => {}
667 }
668 results
669 } else {
670 match value {
671 serde_json::Value::Array(arr) => {
672 if let Ok(idx) = component.parse::<usize>() {
673 if let Some(item) = arr.get(idx) {
674 return Self::jq_all_recursive(item, remaining);
675 }
676 }
677 vec![]
678 }
679 serde_json::Value::Object(obj) => {
680 if let Some(val) = obj.get(component) {
681 return Self::jq_all_recursive(val, remaining);
682 }
683 vec![]
684 }
685 _ => vec![],
686 }
687 }
688 }
689}