Skip to main content

logforth_core/
kv.rs

1// Copyright 2024 FastLabs Developers
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Key-value pairs in a log record or a diagnostic context.
16
17use std::borrow::Borrow;
18use std::borrow::Cow;
19use std::collections::HashMap;
20use std::collections::hash_map;
21use std::fmt;
22use std::slice;
23
24use crate::Error;
25use crate::str::RefStr;
26
27/// A visitor to walk through key-value pairs.
28pub trait Visitor {
29    /// Visit a key-value pair.
30    fn visit(&mut self, key: KeyView, value: ValueView) -> Result<(), Error>;
31}
32
33/// A key in a key-value pair.
34#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
35pub struct Key<'a>(RefStr<'a>);
36
37impl fmt::Display for Key<'_> {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        fmt::Display::fmt(&self.0, f)
40    }
41}
42
43#[cfg(feature = "serde")]
44impl serde::Serialize for Key<'_> {
45    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
46        serializer.collect_str(self)
47    }
48}
49
50impl Borrow<str> for Key<'_> {
51    fn borrow(&self) -> &str {
52        &self.0
53    }
54}
55
56impl Key<'static> {
57    /// Create a new key from a static `&str`.
58    pub const fn new(k: &'static str) -> Key<'static> {
59        Key(RefStr::Static(k))
60    }
61}
62
63impl<'a> Key<'a> {
64    /// Create a new key from a `&str`.
65    ///
66    /// The [`Key::new`] method should be preferred where possible.
67    pub const fn borrowed(k: &'a str) -> Key<'a> {
68        Key(RefStr::Borrowed(k))
69    }
70}
71
72impl Key<'_> {
73    /// Create a borrowed view of this key.
74    pub fn view(&self) -> KeyView<'_> {
75        KeyView(self.0)
76    }
77}
78
79/// An owned key in a key-value pair.
80#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
81pub struct KeyOwned(Cow<'static, str>);
82
83impl Borrow<str> for KeyOwned {
84    fn borrow(&self) -> &str {
85        &self.0
86    }
87}
88
89impl fmt::Display for KeyOwned {
90    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91        fmt::Display::fmt(&self.0, f)
92    }
93}
94
95#[cfg(feature = "serde")]
96impl serde::Serialize for KeyOwned {
97    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
98        serializer.collect_str(self)
99    }
100}
101
102impl KeyOwned {
103    /// Create an owned key.
104    pub fn new(k: impl Into<Cow<'static, str>>) -> KeyOwned {
105        KeyOwned(k.into())
106    }
107}
108
109impl KeyOwned {
110    /// Create a borrowed view of this owned key.
111    pub fn view(&self) -> KeyView<'_> {
112        KeyView(match &self.0 {
113            Cow::Borrowed(s) => RefStr::Static(s),
114            Cow::Owned(s) => RefStr::Borrowed(s),
115        })
116    }
117}
118
119/// A borrowed view of a key in a key-value pair.
120#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
121pub struct KeyView<'a>(RefStr<'a>);
122
123impl Borrow<str> for KeyView<'_> {
124    fn borrow(&self) -> &str {
125        &self.0
126    }
127}
128
129impl fmt::Display for KeyView<'_> {
130    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131        fmt::Display::fmt(&self.0, f)
132    }
133}
134
135#[cfg(feature = "serde")]
136impl serde::Serialize for KeyView<'_> {
137    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
138        serializer.collect_str(self)
139    }
140}
141
142impl KeyView<'_> {
143    /// Convert to an owned key.
144    pub fn to_owned(&self) -> KeyOwned {
145        KeyOwned(self.0.into_cow_static())
146    }
147
148    /// Convert to a `Cow` str.
149    pub fn to_cow(&self) -> Cow<'static, str> {
150        self.0.into_cow_static()
151    }
152
153    /// Get the key string.
154    pub fn as_str(&self) -> &str {
155        self.0.get()
156    }
157}
158
159/// A value captured through its [`fmt::Debug`] representation.
160#[derive(Clone, Copy)]
161pub struct DebugValue<'a>(&'a dyn fmt::Debug);
162
163impl fmt::Debug for DebugValue<'_> {
164    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
165        fmt::Debug::fmt(&self.0, f)
166    }
167}
168
169impl fmt::Display for DebugValue<'_> {
170    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
171        fmt::Debug::fmt(&self.0, f)
172    }
173}
174
175/// A value captured through its [`fmt::Display`] representation.
176#[derive(Clone, Copy)]
177pub struct DisplayValue<'a>(&'a dyn fmt::Display);
178
179impl fmt::Debug for DisplayValue<'_> {
180    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
181        fmt::Display::fmt(&self.0, f)
182    }
183}
184
185impl fmt::Display for DisplayValue<'_> {
186    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
187        fmt::Display::fmt(&self.0, f)
188    }
189}
190
191/// A borrowed view over a list value.
192#[derive(Debug, Clone, Copy)]
193pub struct ListValue<'a>(ListValueState<'a>);
194
195#[derive(Debug, Clone, Copy)]
196enum ListValueState<'a> {
197    Borrowed(&'a [Value<'a>]),
198    Owned(&'a [ValueOwned]),
199}
200
201#[cfg(feature = "serde")]
202impl serde::Serialize for ListValue<'_> {
203    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
204        serializer.collect_seq(self.iter())
205    }
206}
207
208impl<'a> ListValue<'a> {
209    /// Get the number of elements.
210    pub fn len(&self) -> usize {
211        match self.0 {
212            ListValueState::Borrowed(p) => p.len(),
213            ListValueState::Owned(p) => p.len(),
214        }
215    }
216
217    /// Check if this is an empty list.
218    pub fn is_empty(&self) -> bool {
219        match self.0 {
220            ListValueState::Borrowed(p) => p.is_empty(),
221            ListValueState::Owned(p) => p.is_empty(),
222        }
223    }
224
225    /// Get an iterator over the list values.
226    pub fn iter(&self) -> ListValueIter<'a> {
227        match self.0 {
228            ListValueState::Borrowed(v) => ListValueIter(ListValueIterState::Borrowed(v.iter())),
229            ListValueState::Owned(v) => ListValueIter(ListValueIterState::Owned(v.iter())),
230        }
231    }
232}
233
234/// An iterator over list values.
235#[derive(Debug, Clone)]
236pub struct ListValueIter<'a>(ListValueIterState<'a>);
237
238#[derive(Debug, Clone)]
239enum ListValueIterState<'a> {
240    Borrowed(slice::Iter<'a, Value<'a>>),
241    Owned(slice::Iter<'a, ValueOwned>),
242}
243
244impl<'a> Iterator for ListValueIter<'a> {
245    type Item = ValueView<'a>;
246
247    fn next(&mut self) -> Option<Self::Item> {
248        match &mut self.0 {
249            ListValueIterState::Borrowed(v) => v.next().map(|v| v.view()),
250            ListValueIterState::Owned(v) => v.next().map(|v| v.view()),
251        }
252    }
253
254    fn size_hint(&self) -> (usize, Option<usize>) {
255        match &self.0 {
256            ListValueIterState::Borrowed(v) => v.size_hint(),
257            ListValueIterState::Owned(v) => v.size_hint(),
258        }
259    }
260}
261
262/// A borrowed view over a map value.
263#[derive(Debug, Clone, Copy)]
264pub struct MapValue<'a>(MapValueState<'a>);
265
266#[derive(Debug, Clone, Copy)]
267enum MapValueState<'a> {
268    Borrowed(&'a [(Key<'a>, Value<'a>)]),
269    Owned(&'a HashMap<KeyOwned, ValueOwned>),
270}
271
272#[cfg(feature = "serde")]
273impl serde::Serialize for MapValue<'_> {
274    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
275        serializer.collect_map(self.iter())
276    }
277}
278
279impl<'a> MapValue<'a> {
280    /// Get the number of key-values.
281    pub fn len(&self) -> usize {
282        match self.0 {
283            MapValueState::Borrowed(p) => p.len(),
284            MapValueState::Owned(p) => p.len(),
285        }
286    }
287
288    /// Check if there are no key-value pairs.
289    pub fn is_empty(&self) -> bool {
290        match self.0 {
291            MapValueState::Borrowed(p) => p.is_empty(),
292            MapValueState::Owned(p) => p.is_empty(),
293        }
294    }
295
296    /// Get an iterator over the map key-value pairs.
297    pub fn iter(&self) -> MapValueIter<'a> {
298        match self.0 {
299            MapValueState::Borrowed(v) => MapValueIter(MapValueIterState::Borrowed(v.iter())),
300            MapValueState::Owned(v) => MapValueIter(MapValueIterState::Owned(v.iter())),
301        }
302    }
303
304    /// Get the value for a given key.
305    pub fn get(&self, key: &str) -> Option<ValueView<'a>> {
306        match &self.0 {
307            MapValueState::Borrowed(p) => p
308                .iter()
309                .find_map(|(k, v)| if (&*k.0) != key { None } else { Some(v.view()) }),
310            MapValueState::Owned(p) => p.get(key).map(|v| v.view()),
311        }
312    }
313}
314
315/// An iterator over map key-value pairs.
316#[derive(Debug, Clone)]
317pub struct MapValueIter<'a>(MapValueIterState<'a>);
318
319#[derive(Debug, Clone)]
320enum MapValueIterState<'a> {
321    Borrowed(slice::Iter<'a, (Key<'a>, Value<'a>)>),
322    Owned(hash_map::Iter<'a, KeyOwned, ValueOwned>),
323}
324
325impl<'a> Iterator for MapValueIter<'a> {
326    type Item = (KeyView<'a>, ValueView<'a>);
327
328    fn next(&mut self) -> Option<Self::Item> {
329        match &mut self.0 {
330            MapValueIterState::Borrowed(v) => v.next().map(|(k, v)| (k.view(), v.view())),
331            MapValueIterState::Owned(v) => v.next().map(|(k, v)| (k.view(), v.view())),
332        }
333    }
334
335    fn size_hint(&self) -> (usize, Option<usize>) {
336        match &self.0 {
337            MapValueIterState::Borrowed(v) => v.size_hint(),
338            MapValueIterState::Owned(v) => v.size_hint(),
339        }
340    }
341}
342
343/// A borrowed value in a key-value pair.
344#[derive(Debug, Clone)]
345pub struct Value<'a>(ValueState<'a>);
346
347#[derive(Clone)]
348enum ValueState<'a> {
349    None,
350    Bool(bool),
351    I64(i64),
352    U64(u64),
353    F64(f64),
354    I128(i128),
355    U128(u128),
356    Char(char),
357    Str(RefStr<'a>),
358    Bytes(&'a [u8]),
359    List(&'a [Value<'a>]),
360    Map(&'a [(Key<'a>, Value<'a>)]),
361    Debug(&'a dyn fmt::Debug),
362    Display(&'a dyn fmt::Display),
363}
364
365impl fmt::Debug for ValueState<'_> {
366    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
367        match self {
368            ValueState::None => write!(f, "<none>"),
369            ValueState::Bool(v) => v.fmt(f),
370            ValueState::I64(v) => v.fmt(f),
371            ValueState::U64(v) => v.fmt(f),
372            ValueState::F64(v) => v.fmt(f),
373            ValueState::I128(v) => v.fmt(f),
374            ValueState::U128(v) => v.fmt(f),
375            ValueState::Char(v) => v.fmt(f),
376            ValueState::Str(v) => v.fmt(f),
377            ValueState::Bytes(v) => v.fmt(f),
378            ValueState::List(v) => v.fmt(f),
379            ValueState::Map(v) => v.fmt(f),
380            ValueState::Debug(v) => fmt::Debug::fmt(v, f),
381            ValueState::Display(v) => fmt::Display::fmt(v, f),
382        }
383    }
384}
385
386#[cfg(feature = "serde")]
387impl serde::Serialize for Value<'_> {
388    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
389        self.view().serialize(serializer)
390    }
391}
392
393impl Value<'_> {
394    /// Create a borrowed view of this value.
395    pub fn view(&self) -> ValueView<'_> {
396        match self.0 {
397            ValueState::None => ValueView::None,
398            ValueState::Bool(b) => ValueView::Bool(b),
399            ValueState::I64(i) => ValueView::I64(i),
400            ValueState::U64(u) => ValueView::U64(u),
401            ValueState::F64(f) => ValueView::F64(f),
402            ValueState::I128(i) => ValueView::I128(i),
403            ValueState::U128(u) => ValueView::U128(u),
404            ValueState::Char(c) => ValueView::Char(c),
405            ValueState::Str(RefStr::Static(s)) => ValueView::StaticStr(s),
406            ValueState::Str(RefStr::Borrowed(s)) => ValueView::BorrowedStr(s),
407            ValueState::Bytes(b) => ValueView::Bytes(b),
408            ValueState::List(l) => ValueView::List(ListValue(ListValueState::Borrowed(l))),
409            ValueState::Map(m) => ValueView::Map(MapValue(MapValueState::Borrowed(m))),
410            ValueState::Debug(d) => ValueView::Debug(DebugValue(d)),
411            ValueState::Display(d) => ValueView::Display(DisplayValue(d)),
412        }
413    }
414}
415
416impl<'a> Value<'a> {
417    /// Create a value representing the absence of data.
418    pub fn none() -> Value<'a> {
419        Value(ValueState::None)
420    }
421
422    /// Create a value from a borrowed string.
423    pub fn str(s: &'a str) -> Self {
424        Value(ValueState::Str(RefStr::Borrowed(s)))
425    }
426
427    /// Create a value from a static string.
428    pub fn static_str(s: &'static str) -> Self {
429        Value(ValueState::Str(RefStr::Static(s)))
430    }
431
432    /// Create a value from a byte array.
433    pub fn bytes(b: &'a [u8]) -> Self {
434        Value(ValueState::Bytes(b))
435    }
436
437    /// Create a value from a boolean.
438    pub fn bool(b: bool) -> Self {
439        Value(ValueState::Bool(b))
440    }
441
442    /// Create a value from a signed 64-bit integer.
443    pub fn i64(i: i64) -> Self {
444        Value(ValueState::I64(i))
445    }
446
447    /// Create a value from an unsigned 64-bit integer.
448    pub fn u64(u: u64) -> Self {
449        Value(ValueState::U64(u))
450    }
451
452    /// Create a value from a 64-bit floating point number.
453    pub fn f64(f: f64) -> Self {
454        Value(ValueState::F64(f))
455    }
456
457    /// Create a value from a signed 128-bit integer.
458    pub fn i128(i: i128) -> Self {
459        Value(ValueState::I128(i))
460    }
461
462    /// Create a value from an unsigned 128-bit integer.
463    pub fn u128(u: u128) -> Self {
464        Value(ValueState::U128(u))
465    }
466
467    /// Create a value from a Unicode scalar value.
468    pub fn char(c: char) -> Self {
469        Value(ValueState::Char(c))
470    }
471
472    /// Create a value from a borrowed list of values.
473    pub fn list(l: &'a [Value<'a>]) -> Self {
474        Value(ValueState::List(l))
475    }
476
477    /// Create a value from a borrowed map of key-value pairs.
478    pub fn map(m: &'a [(Key<'a>, Value<'a>)]) -> Self {
479        Value(ValueState::Map(m))
480    }
481
482    /// Create a value that is formatted lazily with [`fmt::Debug`].
483    pub fn debug(d: &'a dyn fmt::Debug) -> Self {
484        Value(ValueState::Debug(d))
485    }
486
487    /// Create a value that is formatted lazily with [`fmt::Display`].
488    pub fn display(d: &'a dyn fmt::Display) -> Self {
489        Value(ValueState::Display(d))
490    }
491}
492
493/// An owned value in a key-value pair.
494#[derive(Debug, Clone)]
495pub struct ValueOwned(ValueOwnedState);
496
497#[derive(Debug, Clone)]
498enum ValueOwnedState {
499    None,
500    Bool(bool),
501    I64(i64),
502    U64(u64),
503    F64(f64),
504    I128(i128),
505    U128(u128),
506    Char(char),
507    Str(Cow<'static, str>),
508    #[expect(clippy::box_collection)]
509    Bytes(Box<Vec<u8>>),
510    #[expect(clippy::box_collection)]
511    List(Box<Vec<ValueOwned>>),
512    #[expect(clippy::box_collection)]
513    Map(Box<HashMap<KeyOwned, ValueOwned>>),
514}
515
516#[cfg(feature = "serde")]
517impl serde::Serialize for ValueOwned {
518    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
519        self.view().serialize(serializer)
520    }
521}
522
523impl ValueOwned {
524    /// Create a borrowed view of this owned value.
525    pub fn view(&self) -> ValueView<'_> {
526        match &self.0 {
527            ValueOwnedState::None => ValueView::None,
528            ValueOwnedState::Bool(b) => ValueView::Bool(*b),
529            ValueOwnedState::I64(i) => ValueView::I64(*i),
530            ValueOwnedState::U64(u) => ValueView::U64(*u),
531            ValueOwnedState::F64(f) => ValueView::F64(*f),
532            ValueOwnedState::I128(i) => ValueView::I128(*i),
533            ValueOwnedState::U128(u) => ValueView::U128(*u),
534            ValueOwnedState::Char(c) => ValueView::Char(*c),
535            ValueOwnedState::Str(Cow::Borrowed(s)) => ValueView::StaticStr(s),
536            ValueOwnedState::Str(Cow::Owned(s)) => ValueView::BorrowedStr(s.as_str()),
537            ValueOwnedState::Bytes(b) => ValueView::Bytes(b.as_slice()),
538            ValueOwnedState::List(l) => ValueView::List(ListValue(ListValueState::Owned(l))),
539            ValueOwnedState::Map(m) => ValueView::Map(MapValue(MapValueState::Owned(m))),
540        }
541    }
542}
543
544impl ValueOwned {
545    /// Create an owned value representing the absence of data.
546    pub fn none() -> ValueOwned {
547        ValueOwned(ValueOwnedState::None)
548    }
549
550    /// Create an owned value from a boolean.
551    pub fn bool(b: bool) -> ValueOwned {
552        ValueOwned(ValueOwnedState::Bool(b))
553    }
554
555    /// Create an owned value from a signed 64-bit integer.
556    pub fn i64(i: i64) -> ValueOwned {
557        ValueOwned(ValueOwnedState::I64(i))
558    }
559
560    /// Create an owned value from an unsigned 64-bit integer.
561    pub fn u64(u: u64) -> ValueOwned {
562        ValueOwned(ValueOwnedState::U64(u))
563    }
564
565    /// Create an owned value from a 64-bit floating point number.
566    pub fn f64(f: f64) -> ValueOwned {
567        ValueOwned(ValueOwnedState::F64(f))
568    }
569
570    /// Create an owned value from a signed 128-bit integer.
571    pub fn i128(i: i128) -> ValueOwned {
572        ValueOwned(ValueOwnedState::I128(i))
573    }
574
575    /// Create an owned value from an unsigned 128-bit integer.
576    pub fn u128(u: u128) -> ValueOwned {
577        ValueOwned(ValueOwnedState::U128(u))
578    }
579
580    /// Create an owned value from a Unicode scalar value.
581    pub fn char(c: char) -> ValueOwned {
582        ValueOwned(ValueOwnedState::Char(c))
583    }
584
585    /// Create an owned value from a string.
586    pub fn str(s: impl Into<Cow<'static, str>>) -> ValueOwned {
587        ValueOwned(ValueOwnedState::Str(s.into()))
588    }
589
590    /// Create an owned value from a byte array.
591    pub fn bytes(b: impl Into<Vec<u8>>) -> ValueOwned {
592        ValueOwned(ValueOwnedState::Bytes(Box::new(b.into())))
593    }
594
595    /// Create an owned value from a list of owned values.
596    pub fn list(l: impl IntoIterator<Item = ValueOwned>) -> ValueOwned {
597        ValueOwned(ValueOwnedState::List(Box::new(l.into_iter().collect())))
598    }
599
600    /// Create an owned value from a map of owned key-value pairs.
601    pub fn map(m: impl IntoIterator<Item = (KeyOwned, ValueOwned)>) -> ValueOwned {
602        ValueOwned(ValueOwnedState::Map(Box::new(m.into_iter().collect())))
603    }
604
605    /// Create an owned list value from a vector.
606    pub fn from_vec(v: Vec<ValueOwned>) -> ValueOwned {
607        ValueOwned(ValueOwnedState::List(Box::new(v)))
608    }
609
610    /// Create an owned map value from a hash map.
611    pub fn from_hash_map(m: HashMap<KeyOwned, ValueOwned>) -> ValueOwned {
612        ValueOwned(ValueOwnedState::Map(Box::new(m)))
613    }
614}
615
616/// A borrowed view of a value.
617#[derive(Debug, Clone)]
618#[non_exhaustive]
619pub enum ValueView<'a> {
620    /// The absence of a value.
621    None,
622    /// A borrowed string value.
623    BorrowedStr(&'a str),
624    /// A static string value.
625    StaticStr(&'static str),
626    /// A byte array value.
627    Bytes(&'a [u8]),
628    /// A boolean value.
629    Bool(bool),
630    /// A signed 64-bit integer value.
631    I64(i64),
632    /// An unsigned 64-bit integer value.
633    U64(u64),
634    /// A 64-bit floating point value.
635    F64(f64),
636    /// A signed 128-bit integer value.
637    I128(i128),
638    /// An unsigned 128-bit integer value.
639    U128(u128),
640    /// A Unicode scalar value.
641    Char(char),
642    /// A list value.
643    List(ListValue<'a>),
644    /// A map value.
645    Map(MapValue<'a>),
646    /// A lazily debug-formatted value.
647    Debug(DebugValue<'a>),
648    /// A lazily display-formatted value.
649    Display(DisplayValue<'a>),
650}
651
652impl fmt::Display for ValueView<'_> {
653    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
654        match self {
655            ValueView::None => write!(f, "<none>"),
656            ValueView::BorrowedStr(v) => v.fmt(f),
657            ValueView::StaticStr(v) => v.fmt(f),
658            ValueView::Bytes(v) => {
659                // this follows what `bytes` does:
660                // https://github.com/tokio-rs/bytes/blob/2256e6dc/src/fmt/debug.rs
661                write!(f, "b\"")?;
662                for &b in v.iter() {
663                    // https://doc.rust-lang.org/reference/tokens.html#byte-escapes
664                    if b == b'\n' {
665                        write!(f, "\\n")?;
666                    } else if b == b'\r' {
667                        write!(f, "\\r")?;
668                    } else if b == b'\t' {
669                        write!(f, "\\t")?;
670                    } else if b == b'\\' || b == b'"' {
671                        write!(f, "\\{}", b as char)?;
672                    } else if b == b'\0' {
673                        write!(f, "\\0")?;
674                    // ASCII printable
675                    } else if (0x20..0x7f).contains(&b) {
676                        write!(f, "{}", b as char)?;
677                    } else {
678                        write!(f, "\\x{:02x}", b)?;
679                    }
680                }
681                write!(f, "\"")?;
682                Ok(())
683            }
684            ValueView::Bool(v) => v.fmt(f),
685            ValueView::I64(v) => v.fmt(f),
686            ValueView::U64(v) => v.fmt(f),
687            ValueView::F64(v) => v.fmt(f),
688            ValueView::I128(v) => v.fmt(f),
689            ValueView::U128(v) => v.fmt(f),
690            ValueView::Char(v) => v.fmt(f),
691            ValueView::List(v) => {
692                let mut dbg = f.debug_list();
693                for item in v.iter() {
694                    dbg.entry(&item);
695                }
696                dbg.finish()
697            }
698            ValueView::Map(v) => {
699                let mut dbg = f.debug_map();
700                for (k, v) in v.iter() {
701                    dbg.entry(&k, &v);
702                }
703                dbg.finish()
704            }
705            ValueView::Debug(v) => fmt::Debug::fmt(v, f),
706            ValueView::Display(v) => fmt::Display::fmt(v, f),
707        }
708    }
709}
710
711#[cfg(feature = "serde")]
712impl serde::Serialize for ValueView<'_> {
713    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
714        match &self {
715            ValueView::None => serializer.serialize_none(),
716            ValueView::BorrowedStr(v) => serializer.serialize_str(v),
717            ValueView::StaticStr(v) => serializer.serialize_str(v),
718            ValueView::Bytes(v) => serializer.serialize_bytes(v),
719            ValueView::Bool(v) => serializer.serialize_bool(*v),
720            ValueView::I64(v) => serializer.serialize_i64(*v),
721            ValueView::U64(v) => serializer.serialize_u64(*v),
722            ValueView::F64(v) => serializer.serialize_f64(*v),
723            ValueView::I128(v) => serializer.serialize_i128(*v),
724            ValueView::U128(v) => serializer.serialize_u128(*v),
725            ValueView::Char(v) => serializer.serialize_char(*v),
726            ValueView::List(v) => v.serialize(serializer),
727            ValueView::Map(v) => v.serialize(serializer),
728            ValueView::Debug(v) => serializer.collect_str(v),
729            ValueView::Display(v) => serializer.collect_str(v),
730        }
731    }
732}
733
734impl ValueView<'_> {
735    /// Convert this view into an owned value.
736    pub fn to_owned(&self) -> ValueOwned {
737        match &self {
738            ValueView::None => ValueOwned(ValueOwnedState::None),
739            ValueView::BorrowedStr(s) => {
740                ValueOwned(ValueOwnedState::Str(Cow::Owned(s.to_string())))
741            }
742            ValueView::StaticStr(s) => ValueOwned(ValueOwnedState::Str(Cow::Borrowed(s))),
743            ValueView::Bytes(b) => ValueOwned(ValueOwnedState::Bytes(Box::new(b.to_vec()))),
744            ValueView::Bool(b) => ValueOwned(ValueOwnedState::Bool(*b)),
745            ValueView::I64(i) => ValueOwned(ValueOwnedState::I64(*i)),
746            ValueView::U64(u) => ValueOwned(ValueOwnedState::U64(*u)),
747            ValueView::F64(f) => ValueOwned(ValueOwnedState::F64(*f)),
748            ValueView::I128(i) => ValueOwned(ValueOwnedState::I128(*i)),
749            ValueView::U128(u) => ValueOwned(ValueOwnedState::U128(*u)),
750            ValueView::Char(c) => ValueOwned(ValueOwnedState::Char(*c)),
751            ValueView::List(l) => ValueOwned(ValueOwnedState::List(Box::new(
752                l.iter().map(|v| v.to_owned()).collect(),
753            ))),
754            ValueView::Map(m) => ValueOwned(ValueOwnedState::Map(Box::new(
755                m.iter()
756                    .map(|(k, v)| (k.to_owned(), v.to_owned()))
757                    .collect(),
758            ))),
759            ValueView::Debug(d) => ValueOwned(ValueOwnedState::Str(Cow::Owned(format!("{d:?}")))),
760            ValueView::Display(d) => ValueOwned(ValueOwnedState::Str(Cow::Owned(format!("{d}")))),
761        }
762    }
763}
764
765impl<'a> ValueView<'a> {
766    /// Try to convert this view into a boolean.
767    pub fn to_bool(&self) -> Option<bool> {
768        if let ValueView::Bool(b) = self {
769            Some(*b)
770        } else {
771            None
772        }
773    }
774
775    /// Try to convert this view into a signed 64-bit integer.
776    pub fn to_i64(&self) -> Option<i64> {
777        if let ValueView::I64(i) = self {
778            Some(*i)
779        } else {
780            None
781        }
782    }
783
784    /// Try to convert this view into an unsigned 64-bit integer.
785    pub fn to_u64(&self) -> Option<u64> {
786        if let ValueView::U64(u) = self {
787            Some(*u)
788        } else {
789            None
790        }
791    }
792
793    /// Try to convert this view into a 64-bit floating point number.
794    pub fn to_f64(&self) -> Option<f64> {
795        if let ValueView::F64(f) = self {
796            Some(*f)
797        } else {
798            None
799        }
800    }
801
802    /// Try to convert this view into a signed 128-bit integer.
803    pub fn to_i128(&self) -> Option<i128> {
804        if let ValueView::I128(i) = self {
805            Some(*i)
806        } else {
807            None
808        }
809    }
810
811    /// Try to convert this view into an unsigned 128-bit integer.
812    pub fn to_u128(&self) -> Option<u128> {
813        if let ValueView::U128(u) = self {
814            Some(*u)
815        } else {
816            None
817        }
818    }
819
820    /// Try to convert this view into a Unicode scalar value.
821    pub fn to_char(&self) -> Option<char> {
822        if let ValueView::Char(c) = self {
823            Some(*c)
824        } else {
825            None
826        }
827    }
828
829    /// Try to convert this view into a string slice.
830    pub fn to_str(&self) -> Option<&'a str> {
831        if let ValueView::BorrowedStr(s) = self {
832            Some(*s)
833        } else if let ValueView::StaticStr(s) = self {
834            Some(*s)
835        } else {
836            None
837        }
838    }
839
840    /// Try to convert this view into a static string slice.
841    pub fn to_static_str(&self) -> Option<&'static str> {
842        if let ValueView::StaticStr(s) = self {
843            Some(*s)
844        } else {
845            None
846        }
847    }
848
849    /// Try to convert this view into a display-formatted value.
850    pub fn to_display(&self) -> Option<DisplayValue<'a>> {
851        if let ValueView::Display(d) = self {
852            Some(*d)
853        } else {
854            None
855        }
856    }
857
858    /// Try to convert this view into a list value.
859    pub fn to_list(&self) -> Option<ListValue<'a>> {
860        if let ValueView::List(l) = self {
861            Some(*l)
862        } else {
863            None
864        }
865    }
866
867    /// Try to convert this view into a map value.
868    pub fn to_map(&self) -> Option<MapValue<'a>> {
869        if let ValueView::Map(m) = self {
870            Some(*m)
871        } else {
872            None
873        }
874    }
875
876    /// Try to convert this view into a debug-formatted value.
877    pub fn to_debug(&self) -> Option<DebugValue<'a>> {
878        if let ValueView::Debug(d) = self {
879            Some(*d)
880        } else {
881            None
882        }
883    }
884}
885
886/// A collection of key-value pairs.
887#[derive(Debug, Clone, Copy)]
888pub struct KeyValues<'a>(KeyValuesState<'a>);
889
890#[derive(Debug, Clone, Copy)]
891enum KeyValuesState<'a> {
892    Borrowed(&'a [(Key<'a>, Value<'a>)]),
893    Owned(&'a [(KeyOwned, ValueOwned)]),
894}
895
896impl KeyValues<'_> {
897    /// Create an empty key-value collection.
898    pub fn empty() -> Self {
899        KeyValues(KeyValuesState::Borrowed(&[]))
900    }
901}
902
903impl<'a> KeyValues<'a> {
904    /// Get the number of key-value pairs.
905    pub fn len(&self) -> usize {
906        match self.0 {
907            KeyValuesState::Borrowed(p) => p.len(),
908            KeyValuesState::Owned(p) => p.len(),
909        }
910    }
911
912    /// Check if there are no key-value pairs.
913    pub fn is_empty(&self) -> bool {
914        match self.0 {
915            KeyValuesState::Borrowed(p) => p.is_empty(),
916            KeyValuesState::Owned(p) => p.is_empty(),
917        }
918    }
919
920    /// Get an iterator over the key-value pairs.
921    pub fn iter(&self) -> KeyValuesIter<'a> {
922        match &self.0 {
923            KeyValuesState::Borrowed(p) => KeyValuesIter(KeyValuesIterState::Borrowed(p.iter())),
924            KeyValuesState::Owned(p) => KeyValuesIter(KeyValuesIterState::Owned(p.iter())),
925        }
926    }
927
928    /// Get the value for a given key.
929    pub fn get(&self, key: &str) -> Option<ValueView<'a>> {
930        match &self.0 {
931            KeyValuesState::Borrowed(p) => p
932                .iter()
933                .find_map(|(k, v)| if (&*k.0) != key { None } else { Some(v.view()) }),
934            KeyValuesState::Owned(p) => p
935                .iter()
936                .find_map(|(k, v)| if (&*k.0) != key { None } else { Some(v.view()) }),
937        }
938    }
939
940    /// Visit the key-value pairs with the provided visitor.
941    pub fn visit(&self, visitor: &mut dyn Visitor) -> Result<(), Error> {
942        for (k, v) in self.iter() {
943            visitor.visit(k, v)?;
944        }
945        Ok(())
946    }
947}
948
949impl<'a> From<&'a [(Key<'a>, Value<'a>)]> for KeyValues<'a> {
950    fn from(kvs: &'a [(Key<'a>, Value<'a>)]) -> Self {
951        Self(KeyValuesState::Borrowed(kvs))
952    }
953}
954
955impl<'a> From<&'a [(KeyOwned, ValueOwned)]> for KeyValues<'a> {
956    fn from(kvs: &'a [(KeyOwned, ValueOwned)]) -> Self {
957        Self(KeyValuesState::Owned(kvs))
958    }
959}
960
961/// An iterator over key-value pairs.
962pub struct KeyValuesIter<'a>(KeyValuesIterState<'a>);
963
964enum KeyValuesIterState<'a> {
965    Borrowed(slice::Iter<'a, (Key<'a>, Value<'a>)>),
966    Owned(slice::Iter<'a, (KeyOwned, ValueOwned)>),
967}
968
969impl<'a> Iterator for KeyValuesIter<'a> {
970    type Item = (KeyView<'a>, ValueView<'a>);
971
972    fn next(&mut self) -> Option<Self::Item> {
973        match &mut self.0 {
974            KeyValuesIterState::Borrowed(iter) => iter.next().map(|(k, v)| (k.view(), v.view())),
975            KeyValuesIterState::Owned(iter) => iter.next().map(|(k, v)| (k.view(), v.view())),
976        }
977    }
978
979    fn size_hint(&self) -> (usize, Option<usize>) {
980        match &self.0 {
981            KeyValuesIterState::Borrowed(iter) => iter.size_hint(),
982            KeyValuesIterState::Owned(iter) => iter.size_hint(),
983        }
984    }
985}