1#![warn(missing_docs)]
4#![allow(clippy::uninlined_format_args)]
5#![forbid(unsafe_code)]
6
7mod deserializer;
8mod extensions;
9mod macros;
10mod serializer;
11mod value_serde;
12mod variables;
13
14use std::{
15 borrow::{Borrow, Cow},
16 fmt::{self, Display, Formatter, Write},
17 ops::Deref,
18 sync::Arc,
19};
20
21use bytes::Bytes;
22pub use deserializer::{DeserializerError, from_value};
23pub use extensions::Extensions;
24#[doc(hidden)]
25pub use indexmap;
26use indexmap::IndexMap;
27use serde::{Deserialize, Deserializer, Serialize, Serializer};
28pub use serde_json::Number;
29pub use serializer::{SerializerError, to_value};
30#[cfg(feature = "raw_value")]
31pub use value_serde::RAW_VALUE_TOKEN;
32pub use variables::Variables;
33
34#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
38pub struct Name(Arc<str>);
39
40impl Serialize for Name {
41 fn serialize<S: Serializer>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> {
42 serializer.serialize_str(&self.0)
43 }
44}
45
46impl Name {
47 pub fn new(name: impl AsRef<str>) -> Self {
49 Self(name.as_ref().into())
50 }
51
52 #[must_use]
54 pub fn as_str(&self) -> &str {
55 &self.0
56 }
57}
58
59impl AsRef<str> for Name {
60 fn as_ref(&self) -> &str {
61 &self.0
62 }
63}
64
65impl Borrow<str> for Name {
66 fn borrow(&self) -> &str {
67 &self.0
68 }
69}
70
71impl Deref for Name {
72 type Target = str;
73
74 fn deref(&self) -> &Self::Target {
75 &self.0
76 }
77}
78
79impl Display for Name {
80 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
81 Display::fmt(&self.0, f)
82 }
83}
84
85impl PartialEq<String> for Name {
86 fn eq(&self, other: &String) -> bool {
87 self.as_str() == other
88 }
89}
90impl PartialEq<str> for Name {
91 fn eq(&self, other: &str) -> bool {
92 self.as_str() == other
93 }
94}
95impl PartialEq<Name> for String {
96 fn eq(&self, other: &Name) -> bool {
97 self == other.as_str()
98 }
99}
100impl PartialEq<Name> for str {
101 fn eq(&self, other: &Name) -> bool {
102 other == self
103 }
104}
105impl<'a> PartialEq<&'a str> for Name {
106 fn eq(&self, other: &&'a str) -> bool {
107 self == *other
108 }
109}
110impl PartialEq<Name> for &'_ str {
111 fn eq(&self, other: &Name) -> bool {
112 other == self
113 }
114}
115
116impl<'de> Deserialize<'de> for Name {
117 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
118 Ok(Self(
119 String::deserialize(deserializer)?.into_boxed_str().into(),
120 ))
121 }
122}
123
124#[derive(Clone, Debug, Default, Eq)]
132pub enum ConstValue {
133 #[default]
135 Null,
136 Number(Number),
138 String(String),
140 Boolean(bool),
142 Binary(Bytes),
144 Enum(Name),
146 List(Vec<ConstValue>),
148 Object(IndexMap<Name, ConstValue>),
150}
151
152impl PartialEq for ConstValue {
153 fn eq(&self, other: &ConstValue) -> bool {
154 match (self, other) {
155 (ConstValue::Null, ConstValue::Null) => true,
156 (ConstValue::Number(a), ConstValue::Number(b)) => a == b,
157 (ConstValue::Boolean(a), ConstValue::Boolean(b)) => a == b,
158 (ConstValue::String(a), ConstValue::String(b)) => a == b,
159 (ConstValue::Enum(a), ConstValue::String(b)) => a == b,
160 (ConstValue::String(a), ConstValue::Enum(b)) => a == b,
161 (ConstValue::Enum(a), ConstValue::Enum(b)) => a == b,
162 (ConstValue::Binary(a), ConstValue::Binary(b)) => a == b,
163 (ConstValue::List(a), ConstValue::List(b)) => {
164 if a.len() != b.len() {
165 return false;
166 }
167 a.iter().zip(b.iter()).all(|(a, b)| a == b)
168 }
169 (ConstValue::Object(a), ConstValue::Object(b)) => {
170 if a.len() != b.len() {
171 return false;
172 }
173 for (a_key, a_value) in a.iter() {
174 if let Some(b_value) = b.get(a_key.as_str()) {
175 if b_value != a_value {
176 return false;
177 }
178 } else {
179 return false;
180 }
181 }
182
183 true
184 }
185 _ => false,
186 }
187 }
188}
189
190impl From<()> for ConstValue {
191 fn from((): ()) -> Self {
192 ConstValue::Null
193 }
194}
195
196macro_rules! from_integer {
197 ($($ty:ident),*) => {
198 $(
199 impl From<$ty> for ConstValue {
200 #[inline]
201 fn from(n: $ty) -> Self {
202 ConstValue::Number(n.into())
203 }
204 }
205 )*
206 };
207}
208
209from_integer!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);
210
211impl From<f32> for ConstValue {
212 #[inline]
213 fn from(f: f32) -> Self {
214 From::from(f as f64)
215 }
216}
217
218impl From<f64> for ConstValue {
219 #[inline]
220 fn from(f: f64) -> Self {
221 Number::from_f64(f).map_or(ConstValue::Null, ConstValue::Number)
222 }
223}
224
225impl From<bool> for ConstValue {
226 #[inline]
227 fn from(value: bool) -> Self {
228 ConstValue::Boolean(value)
229 }
230}
231
232impl From<String> for ConstValue {
233 #[inline]
234 fn from(value: String) -> Self {
235 ConstValue::String(value)
236 }
237}
238
239impl From<&String> for ConstValue {
240 #[inline]
241 fn from(value: &String) -> Self {
242 ConstValue::String(value.clone())
243 }
244}
245
246impl From<Name> for ConstValue {
247 #[inline]
248 fn from(value: Name) -> Self {
249 ConstValue::Enum(value)
250 }
251}
252
253impl<'a> From<&'a str> for ConstValue {
254 #[inline]
255 fn from(value: &'a str) -> Self {
256 ConstValue::String(value.into())
257 }
258}
259
260impl<'a> From<Cow<'a, str>> for ConstValue {
261 #[inline]
262 fn from(f: Cow<'a, str>) -> Self {
263 ConstValue::String(f.into_owned())
264 }
265}
266
267impl<T: Into<ConstValue>> From<Option<T>> for ConstValue {
268 #[inline]
269 fn from(nullable: Option<T>) -> Self {
270 match nullable {
271 Some(value) => value.into(),
272 None => ConstValue::Null,
273 }
274 }
275}
276
277impl<T: Into<ConstValue>> FromIterator<T> for ConstValue {
278 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
279 ConstValue::List(iter.into_iter().map(Into::into).collect())
280 }
281}
282
283impl<'a, T: Clone + Into<ConstValue>> From<&'a [T]> for ConstValue {
284 fn from(f: &'a [T]) -> Self {
285 ConstValue::List(f.iter().cloned().map(Into::into).collect())
286 }
287}
288
289impl<T: Into<ConstValue>> From<Vec<T>> for ConstValue {
290 fn from(f: Vec<T>) -> Self {
291 ConstValue::List(f.into_iter().map(Into::into).collect())
292 }
293}
294
295impl From<IndexMap<Name, ConstValue>> for ConstValue {
296 fn from(f: IndexMap<Name, ConstValue>) -> Self {
297 ConstValue::Object(f)
298 }
299}
300
301impl ConstValue {
302 #[must_use]
304 pub fn into_value(self) -> Value {
305 match self {
306 Self::Null => Value::Null,
307 Self::Number(num) => Value::Number(num),
308 Self::String(s) => Value::String(s),
309 Self::Boolean(b) => Value::Boolean(b),
310 Self::Binary(bytes) => Value::Binary(bytes),
311 Self::Enum(v) => Value::Enum(v),
312 Self::List(items) => {
313 Value::List(items.into_iter().map(ConstValue::into_value).collect())
314 }
315 Self::Object(map) => Value::Object(
316 map.into_iter()
317 .map(|(key, value)| (key, value.into_value()))
318 .collect(),
319 ),
320 }
321 }
322
323 pub fn into_json(self) -> serde_json::Result<serde_json::Value> {
330 self.try_into()
331 }
332
333 pub fn from_json(json: serde_json::Value) -> serde_json::Result<Self> {
340 json.try_into()
341 }
342}
343
344impl Display for ConstValue {
345 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
346 match self {
347 Self::Number(num) => write!(f, "{}", *num),
348 Self::String(val) => write_quoted(val, f),
349 Self::Boolean(true) => f.write_str("true"),
350 Self::Boolean(false) => f.write_str("false"),
351 Self::Binary(bytes) => write_binary(bytes, f),
352 Self::Null => f.write_str("null"),
353 Self::Enum(name) => f.write_str(name),
354 Self::List(items) => write_list(items, f),
355 Self::Object(map) => write_object(map, f),
356 }
357 }
358}
359
360impl TryFrom<serde_json::Value> for ConstValue {
361 type Error = serde_json::Error;
362 fn try_from(value: serde_json::Value) -> Result<Self, Self::Error> {
363 Self::deserialize(value)
364 }
365}
366
367impl TryFrom<ConstValue> for serde_json::Value {
368 type Error = serde_json::Error;
369 fn try_from(value: ConstValue) -> Result<Self, Self::Error> {
370 serde_json::to_value(value)
371 }
372}
373
374#[derive(Clone, Debug, Default, PartialEq, Eq)]
383pub enum Value {
384 Variable(Name),
386 #[default]
388 Null,
389 Number(Number),
391 String(String),
393 Boolean(bool),
395 Binary(Bytes),
397 Enum(Name),
399 List(Vec<Value>),
401 Object(IndexMap<Name, Value>),
403}
404
405impl Value {
406 pub fn into_const_with<E>(
409 self,
410 mut f: impl FnMut(Name) -> Result<ConstValue, E>,
411 ) -> Result<ConstValue, E> {
412 self.into_const_with_mut(&mut f)
413 }
414
415 fn into_const_with_mut<E>(
416 self,
417 f: &mut impl FnMut(Name) -> Result<ConstValue, E>,
418 ) -> Result<ConstValue, E> {
419 Ok(match self {
420 Self::Variable(name) => f(name)?,
421 Self::Null => ConstValue::Null,
422 Self::Number(num) => ConstValue::Number(num),
423 Self::String(s) => ConstValue::String(s),
424 Self::Boolean(b) => ConstValue::Boolean(b),
425 Self::Binary(v) => ConstValue::Binary(v),
426 Self::Enum(v) => ConstValue::Enum(v),
427 Self::List(items) => ConstValue::List(
428 items
429 .into_iter()
430 .map(|value| value.into_const_with_mut(f))
431 .collect::<Result<_, _>>()?,
432 ),
433 Self::Object(map) => ConstValue::Object(
434 map.into_iter()
435 .map(|(key, value)| Ok((key, value.into_const_with_mut(f)?)))
436 .collect::<Result<_, _>>()?,
437 ),
438 })
439 }
440
441 #[must_use]
445 pub fn into_const(self) -> Option<ConstValue> {
446 self.into_const_with(|_| Err(())).ok()
447 }
448
449 pub fn into_json(self) -> serde_json::Result<serde_json::Value> {
456 self.try_into()
457 }
458
459 pub fn from_json(json: serde_json::Value) -> serde_json::Result<Self> {
466 json.try_into()
467 }
468}
469
470impl Display for Value {
471 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
472 match self {
473 Self::Variable(name) => write!(f, "${}", name),
474 Self::Number(num) => write!(f, "{}", *num),
475 Self::String(val) => write_quoted(val, f),
476 Self::Boolean(true) => f.write_str("true"),
477 Self::Boolean(false) => f.write_str("false"),
478 Self::Binary(bytes) => write_binary(bytes, f),
479 Self::Null => f.write_str("null"),
480 Self::Enum(name) => f.write_str(name),
481 Self::List(items) => write_list(items, f),
482 Self::Object(map) => write_object(map, f),
483 }
484 }
485}
486
487impl From<ConstValue> for Value {
488 fn from(value: ConstValue) -> Self {
489 value.into_value()
490 }
491}
492
493impl TryFrom<serde_json::Value> for Value {
494 type Error = serde_json::Error;
495 fn try_from(value: serde_json::Value) -> Result<Self, Self::Error> {
496 Self::deserialize(value)
497 }
498}
499impl TryFrom<Value> for serde_json::Value {
500 type Error = serde_json::Error;
501 fn try_from(value: Value) -> Result<Self, Self::Error> {
502 serde_json::to_value(value)
503 }
504}
505
506fn write_quoted(s: &str, f: &mut Formatter<'_>) -> fmt::Result {
507 f.write_char('"')?;
508 for c in s.chars() {
509 match c {
510 '\r' => f.write_str("\\r"),
511 '\n' => f.write_str("\\n"),
512 '\t' => f.write_str("\\t"),
513 '"' => f.write_str("\\\""),
514 '\\' => f.write_str("\\\\"),
515 c if c.is_control() => write!(f, "\\u{:04}", c as u32),
516 c => f.write_char(c),
517 }?
518 }
519 f.write_char('"')
520}
521
522fn write_binary(bytes: &[u8], f: &mut Formatter<'_>) -> fmt::Result {
523 f.write_char('[')?;
524 let mut iter = bytes.iter().copied();
525 if let Some(value) = iter.next() {
526 value.fmt(f)?;
527 }
528 for value in iter {
529 f.write_str(", ")?;
530 value.fmt(f)?;
531 }
532 f.write_char(']')
533}
534
535fn write_list<T: Display>(list: impl IntoIterator<Item = T>, f: &mut Formatter<'_>) -> fmt::Result {
536 f.write_char('[')?;
537 let mut iter = list.into_iter();
538 if let Some(item) = iter.next() {
539 item.fmt(f)?;
540 }
541 for item in iter {
542 f.write_str(", ")?;
543 item.fmt(f)?;
544 }
545 f.write_char(']')
546}
547
548fn write_object<K: Display, V: Display>(
549 object: impl IntoIterator<Item = (K, V)>,
550 f: &mut Formatter<'_>,
551) -> fmt::Result {
552 f.write_char('{')?;
553 let mut iter = object.into_iter();
554 if let Some((name, value)) = iter.next() {
555 write!(f, "{}: {}", name, value)?;
556 }
557 for (name, value) in iter {
558 f.write_str(", ")?;
559 write!(f, "{}: {}", name, value)?;
560 }
561 f.write_char('}')
562}