Skip to main content

sval/data/
map.rs

1use crate::{std::fmt, Result, Stream, Value};
2
3/**
4An adapter that streams a slice of key-value pairs as a map.
5 */
6#[repr(transparent)]
7pub struct MapSlice<K, V>([(K, V)]);
8
9impl<K, V> MapSlice<K, V> {
10    /**
11    Treat a slice of key-value pairs as a map.
12     */
13    pub const fn new<'a>(map: &'a [(K, V)]) -> &'a Self {
14        // SAFETY: `MapSlice` and `[(K, V)]` have the same ABI
15        unsafe { &*(map as *const _ as *const MapSlice<K, V>) }
16    }
17
18    /**
19    Get a reference to the underlying slice.
20     */
21    pub const fn as_slice(&self) -> &[(K, V)] {
22        &self.0
23    }
24}
25
26impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for MapSlice<K, V> {
27    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28        fmt::Debug::fmt(&self.0, f)
29    }
30}
31
32impl<K, V> AsRef<[(K, V)]> for MapSlice<K, V> {
33    fn as_ref(&self) -> &[(K, V)] {
34        &self.0
35    }
36}
37
38impl<K: Value, V: Value> Value for MapSlice<K, V> {
39    fn stream<'sval, S: Stream<'sval> + ?Sized>(&'sval self, stream: &mut S) -> Result {
40        stream.map_begin(Some(self.0.len()))?;
41
42        for (k, v) in self.0.iter() {
43            stream.map_key_begin()?;
44            stream.value(k)?;
45            stream.map_key_end()?;
46
47            stream.map_value_begin()?;
48            stream.value(v)?;
49            stream.map_value_end()?;
50        }
51
52        stream.map_end()
53    }
54}
55
56#[cfg(feature = "alloc")]
57mod alloc_support {
58    use super::*;
59    use crate::std::collections::BTreeMap;
60
61    impl<K: Value, V: Value> Value for BTreeMap<K, V> {
62        fn stream<'sval, S: Stream<'sval> + ?Sized>(&'sval self, stream: &mut S) -> Result {
63            stream.map_begin(Some(self.len()))?;
64
65            for (k, v) in self {
66                stream.map_key_begin()?;
67                stream.value(k)?;
68                stream.map_key_end()?;
69
70                stream.map_value_begin()?;
71                stream.value(v)?;
72                stream.map_value_end()?;
73            }
74
75            stream.map_end()
76        }
77    }
78}
79
80#[cfg(feature = "std")]
81mod std_support {
82    use super::*;
83    use crate::std::{collections::HashMap, hash::BuildHasher};
84
85    impl<K: Value, V: Value, H: BuildHasher> Value for HashMap<K, V, H> {
86        fn stream<'sval, S: Stream<'sval> + ?Sized>(&'sval self, stream: &mut S) -> Result {
87            stream.map_begin(Some(self.len()))?;
88
89            for (k, v) in self {
90                stream.map_key_begin()?;
91                stream.value(k)?;
92                stream.map_key_end()?;
93
94                stream.map_value_begin()?;
95                stream.value(v)?;
96                stream.map_value_end()?;
97            }
98
99            stream.map_end()
100        }
101    }
102}