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