1use num_bigint::BigInt;
2
3use crate::{identifier::Identifier, prelude_internal::*, text::Text};
4
5#[derive(Debug, Clone, PartialEq, Copy)]
6pub enum ValueKind {
7 Hole,
8 Null,
9 Bool,
10 Integer,
11 F32,
12 F64,
13 Text,
14 Array,
15 Tuple,
16 Map,
17 PartialMap,
18}
19
20impl core::fmt::Display for ValueKind {
21 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
22 match self {
23 Self::Hole => write!(f, "hole"),
24 Self::Null => write!(f, "null"),
25 Self::Bool => write!(f, "bool"),
26 Self::Integer => write!(f, "integer"),
27 Self::F32 => write!(f, "f32"),
28 Self::F64 => write!(f, "f64"),
29 Self::Text => write!(f, "text"),
30 Self::Array => write!(f, "array"),
31 Self::Tuple => write!(f, "tuple"),
32 Self::Map => write!(f, "map"),
33 Self::PartialMap => write!(f, "partial-map"),
34 }
35 }
36}
37
38#[derive(Debug, Clone, PartialEq)]
39pub enum PrimitiveValue {
40 Null,
41 Bool(bool),
42 Integer(BigInt),
43 F32(f32),
44 F64(f64),
45 Text(Text),
51}
52
53impl PrimitiveValue {
54 pub fn as_text(&self) -> Option<&Text> {
56 if let Self::Text(text) = self {
57 Some(text)
58 } else {
59 None
60 }
61 }
62
63 pub fn as_str(&self) -> Option<&str> {
65 self.as_text().map(|t| t.as_str())
66 }
67
68 pub(crate) fn kind(&self) -> ValueKind {
69 match self {
70 Self::Null => ValueKind::Null,
71 Self::Bool(_) => ValueKind::Bool,
72 Self::Integer(_) => ValueKind::Integer,
73 Self::F32(_) => ValueKind::F32,
74 Self::F64(_) => ValueKind::F64,
75 Self::Text(_) => ValueKind::Text,
76 }
77 }
78}
79
80#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
81pub enum ObjectKey {
103 Number(BigInt),
104 String(String),
105 Tuple(Tuple<ObjectKey>),
106}
107
108impl core::fmt::Display for ObjectKey {
109 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
110 match self {
111 ObjectKey::Number(n) => write!(f, "{}", n),
112 ObjectKey::String(s) => {
113 write!(f, "\"")?;
114 for c in s.chars() {
115 match c {
116 '"' => write!(f, "\\\"")?,
117 '\\' => write!(f, "\\\\")?,
118 _ => write!(f, "{}", c)?,
119 }
120 }
121 write!(f, "\"")
122 }
123 ObjectKey::Tuple(t) => write!(f, "{}", t),
124 }
125 }
126}
127
128impl From<&str> for ObjectKey {
129 fn from(s: &str) -> Self {
130 ObjectKey::String(s.to_string())
131 }
132}
133
134impl From<String> for ObjectKey {
135 fn from(s: String) -> Self {
136 ObjectKey::String(s)
137 }
138}
139
140impl From<bool> for ObjectKey {
141 fn from(b: bool) -> Self {
142 ObjectKey::String(if b { "true" } else { "false" }.to_string())
143 }
144}
145
146macro_rules! impl_from_int_for_object_key {
147 ($($ty:ty),*) => {
148 $(
149 impl From<$ty> for ObjectKey {
150 fn from(n: $ty) -> Self {
151 ObjectKey::Number(BigInt::from(n))
152 }
153 }
154 )*
155 };
156}
157
158impl_from_int_for_object_key!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
159
160impl From<BigInt> for ObjectKey {
161 fn from(n: BigInt) -> Self {
162 ObjectKey::Number(n)
163 }
164}
165
166#[derive(Debug, Clone, PartialEq, Eq, Hash)]
179pub enum PartialObjectKey {
180 Number(BigInt),
181 String(String),
182 Hole(Option<Identifier>),
184 Tuple(Tuple<PartialObjectKey>),
186}
187
188impl PartialObjectKey {
189 pub fn contains_anonymous_hole(&self) -> bool {
194 match self {
195 PartialObjectKey::Hole(None) => true,
196 PartialObjectKey::Hole(Some(_))
197 | PartialObjectKey::Number(_)
198 | PartialObjectKey::String(_) => false,
199 PartialObjectKey::Tuple(items) => items.iter().any(Self::contains_anonymous_hole),
200 }
201 }
202}
203
204impl core::fmt::Display for PartialObjectKey {
205 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
206 match self {
207 PartialObjectKey::Number(n) => write!(f, "{}", n),
208 PartialObjectKey::String(s) => {
209 write!(f, "\"")?;
210 for c in s.chars() {
211 match c {
212 '"' => write!(f, "\\\"")?,
213 '\\' => write!(f, "\\\\")?,
214 _ => write!(f, "{}", c)?,
215 }
216 }
217 write!(f, "\"")
218 }
219 PartialObjectKey::Hole(None) => write!(f, "!"),
220 PartialObjectKey::Hole(Some(label)) => write!(f, "!{}", label),
221 PartialObjectKey::Tuple(t) => write!(f, "{}", t),
222 }
223 }
224}
225
226impl From<ObjectKey> for PartialObjectKey {
227 fn from(key: ObjectKey) -> Self {
228 match key {
229 ObjectKey::Number(n) => PartialObjectKey::Number(n),
230 ObjectKey::String(s) => PartialObjectKey::String(s),
231 ObjectKey::Tuple(t) => PartialObjectKey::Tuple(Tuple(
232 t.0.into_iter().map(PartialObjectKey::from).collect(),
233 )),
234 }
235 }
236}
237
238#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
240#[error("PartialObjectKey contains a hole and cannot be converted to ObjectKey")]
241pub struct HoleKeyError;
242
243impl TryFrom<PartialObjectKey> for ObjectKey {
244 type Error = HoleKeyError;
245
246 fn try_from(key: PartialObjectKey) -> Result<Self, Self::Error> {
247 match key {
248 PartialObjectKey::Number(n) => Ok(ObjectKey::Number(n)),
249 PartialObjectKey::String(s) => Ok(ObjectKey::String(s)),
250 PartialObjectKey::Hole(_) => Err(HoleKeyError),
251 PartialObjectKey::Tuple(t) => {
252 let keys: Result<Vec<ObjectKey>, _> =
253 t.0.into_iter().map(ObjectKey::try_from).collect();
254 Ok(ObjectKey::Tuple(Tuple(keys?)))
255 }
256 }
257 }
258}
259
260#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Plural, Default)]
261pub struct Tuple<T>(pub Vec<T>);
262
263impl core::fmt::Display for Tuple<ObjectKey> {
264 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
265 write!(f, "(")?;
266 for (i, item) in self.0.iter().enumerate() {
267 if i != 0 {
268 write!(f, ", ")?;
269 }
270 write!(f, "{}", item)?;
271 }
272 write!(f, ")")
273 }
274}
275
276impl core::fmt::Display for Tuple<PartialObjectKey> {
277 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
278 write!(f, "(")?;
279 for (i, item) in self.0.iter().enumerate() {
280 if i != 0 {
281 write!(f, ", ")?;
282 }
283 write!(f, "{}", item)?;
284 }
285 write!(f, ")")
286 }
287}
288
289impl From<bool> for PrimitiveValue {
294 fn from(b: bool) -> Self {
295 PrimitiveValue::Bool(b)
296 }
297}
298
299macro_rules! impl_from_int_for_primitive_value {
300 ($($ty:ty),*) => {
301 $(
302 impl From<$ty> for PrimitiveValue {
303 fn from(n: $ty) -> Self {
304 PrimitiveValue::Integer(BigInt::from(n))
305 }
306 }
307 )*
308 };
309}
310
311impl_from_int_for_primitive_value!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
312
313impl From<f32> for PrimitiveValue {
314 fn from(n: f32) -> Self {
315 PrimitiveValue::F32(n)
316 }
317}
318
319impl From<f64> for PrimitiveValue {
320 fn from(n: f64) -> Self {
321 PrimitiveValue::F64(n)
322 }
323}
324
325impl From<&str> for PrimitiveValue {
326 fn from(s: &str) -> Self {
327 PrimitiveValue::Text(Text::plaintext(s))
328 }
329}
330
331impl From<String> for PrimitiveValue {
332 fn from(s: String) -> Self {
333 PrimitiveValue::Text(Text::plaintext(s))
334 }
335}
336
337impl From<Text> for PrimitiveValue {
338 fn from(t: Text) -> Self {
339 PrimitiveValue::Text(t)
340 }
341}