1use crate::{
4 ffi::{
5 boxed::AscRef,
6 buf::AscTypedArray,
7 str::AscString,
8 sys,
9 value::{AscJsonValue, AscJsonValueData},
10 },
11 num::BigInt,
12};
13use indexmap::IndexMap;
14use std::{
15 borrow::Cow,
16 error::Error,
17 fmt::{self, Debug, Display, Formatter},
18 str::FromStr,
19};
20
21#[derive(Clone, Debug, Default, Eq, PartialEq)]
23pub enum Value {
24 #[default]
25 Null,
26 Bool(bool),
27 Number(Number),
28 String(String),
29 Array(Vec<Value>),
30 Object(IndexMap<String, Value>),
31}
32
33impl Value {
34 fn from_raw(raw: &AscRef<AscJsonValue>) -> Self {
36 match raw.data() {
37 AscJsonValueData::Null(()) => Self::Null,
38 AscJsonValueData::Bool(value) => Self::Bool(value),
39 AscJsonValueData::Number(value) => {
40 Self::Number(Number(Cow::Owned(value.to_string_lossy())))
41 }
42 AscJsonValueData::String(value) => Self::String(value.to_string_lossy()),
43 AscJsonValueData::Array(value) => Self::Array(
44 value
45 .as_slice()
46 .iter()
47 .map(|value| Self::from_raw(value.as_asc_ref()))
48 .collect(),
49 ),
50 AscJsonValueData::Object(value) => Self::Object(
51 value
52 .entries()
53 .iter()
54 .map(|entry| {
55 let entry = entry.as_asc_ref();
56 (
57 entry.key().to_string_lossy(),
58 Self::from_raw(entry.value().as_asc_ref()),
59 )
60 })
61 .collect(),
62 ),
63 }
64 }
65
66 pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
68 let bytes = bytes.as_ref();
69 let array = AscTypedArray::from_bytes(bytes);
70 let raw = unsafe { &*sys::json__from_bytes(array.as_ptr()) };
71
72 Self::from_raw(raw)
73 }
74
75 pub fn try_from_bytes(bytes: impl AsRef<[u8]>) -> Result<Self, ParseError> {
77 let bytes = bytes.as_ref();
78 let array = AscTypedArray::from_bytes(bytes);
79 let result = unsafe { &*sys::json__try_from_bytes(array.as_ptr()) };
80 let raw = result.as_std_result().map_err(|_| ParseError)?.as_asc_ref();
81
82 Ok(Self::from_raw(raw))
83 }
84
85 pub fn as_null(&self) -> Option<()> {
88 match self {
89 Self::Null => Some(()),
90 _ => None,
91 }
92 }
93
94 pub fn as_bool(&self) -> Option<bool> {
97 match self {
98 Self::Bool(value) => Some(*value),
99 _ => None,
100 }
101 }
102
103 pub fn as_number(&self) -> Option<&Number> {
106 match self {
107 Self::Number(value) => Some(value),
108 _ => None,
109 }
110 }
111
112 pub fn as_string(&self) -> Option<&str> {
115 match self {
116 Self::String(value) => Some(value),
117 _ => None,
118 }
119 }
120
121 pub fn as_array(&self) -> Option<&[Self]> {
124 match self {
125 Self::Array(value) => Some(value),
126 _ => None,
127 }
128 }
129
130 pub fn as_object(&self) -> Option<&IndexMap<String, Self>> {
133 match self {
134 Self::Object(value) => Some(value),
135 _ => None,
136 }
137 }
138}
139
140impl Display for Value {
141 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
142 match self {
143 Self::Null => f.write_str("null"),
144 Self::Bool(value) => write!(f, "{value}"),
145 Self::Number(value) => write!(f, "{value}"),
146 Self::String(value) => write!(f, "{value:?}"),
147 Self::Array(value) => {
148 f.write_str("[")?;
149 for (i, value) in value.iter().enumerate() {
150 if i > 0 {
151 f.write_str(",")?;
152 }
153 write!(f, "{value}")?;
154 }
155 f.write_str("]")
156 }
157 Self::Object(value) => {
158 f.write_str("{")?;
159 for (i, (key, value)) in value.iter().enumerate() {
160 if i > 0 {
161 f.write_str(",")?;
162 }
163 write!(f, "\"{key}\":{value}")?;
164 }
165 f.write_str("}")
166 }
167 }
168 }
169}
170
171#[derive(Clone, Eq, PartialEq)]
173pub struct Number(Cow<'static, str>);
174
175impl Number {
176 pub fn to_big_int(&self) -> BigInt {
178 let str = AscString::new(&self.0);
179 let raw = unsafe { &*sys::json__to_big_int(str.as_ptr()) };
180 BigInt::from_raw(raw)
181 }
182
183 pub fn to_f64(&self) -> f64 {
185 let str = AscString::new(&self.0);
186 unsafe { sys::json__to_f64(str.as_ptr()) }
187 }
188
189 pub fn to_i64(&self) -> i64 {
191 let str = AscString::new(&self.0);
192 unsafe { sys::json__to_i64(str.as_ptr()) }
193 }
194
195 pub fn to_u64(&self) -> u64 {
197 let str = AscString::new(&self.0);
198 unsafe { sys::json__to_u64(str.as_ptr()) }
199 }
200}
201
202impl Debug for Number {
203 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
204 f.write_str(&self.0)
205 }
206}
207
208impl Default for Number {
209 fn default() -> Self {
210 Self(Cow::Borrowed("0"))
211 }
212}
213
214impl Display for Number {
215 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
216 f.write_str(&self.0)
217 }
218}
219
220impl FromStr for Value {
221 type Err = ParseError;
222
223 fn from_str(s: &str) -> Result<Self, Self::Err> {
224 Self::try_from_bytes(s)
225 }
226}
227
228#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
230pub struct ParseError;
231
232impl Display for ParseError {
233 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
234 f.write_str("JSON parse error")
235 }
236}
237
238impl Error for ParseError {}