1pub extern crate value_bag;
20
21use std::fmt;
22use std::slice;
23
24use value_bag::OwnedValueBag;
25use value_bag::ValueBag;
26
27use crate::Error;
28use crate::str::Str;
29
30pub trait Visitor {
32 fn visit(&mut self, key: Key, value: Value) -> Result<(), Error>;
34}
35
36pub type Value<'a> = ValueBag<'a>;
38
39#[derive(Debug, Clone)]
41pub struct Key<'a>(Str<'a>);
42
43impl<'a> Key<'a> {
44 pub fn into_string(self) -> String {
46 self.0.into_string()
47 }
48
49 pub fn to_owned(&self) -> KeyOwned {
51 KeyOwned(self.0.to_owned())
52 }
53
54 pub fn as_str(&self) -> &str {
56 self.0.get()
57 }
58
59 pub fn coerce(&self) -> Key<'_> {
61 Key(self.0.by_ref())
62 }
63}
64
65impl fmt::Display for Key<'_> {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 fmt::Display::fmt(&self.0, f)
68 }
69}
70
71impl<'a> From<Str<'a>> for Key<'a> {
72 fn from(s: Str<'a>) -> Self {
73 Key(s)
74 }
75}
76
77impl<'a> From<&'a str> for Key<'a> {
78 fn from(s: &'a str) -> Self {
79 Key(Str::from(s))
80 }
81}
82
83pub type ValueOwned = OwnedValueBag;
85
86#[derive(Debug, Clone)]
88pub struct KeyOwned(Str<'static>);
89
90impl KeyOwned {
91 pub fn by_ref(&self) -> Key<'_> {
93 Key(self.0.by_ref())
94 }
95}
96
97impl fmt::Display for KeyOwned {
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99 fmt::Display::fmt(&self.0, f)
100 }
101}
102
103pub struct KeyValues<'a>(KeyValuesState<'a>);
105
106enum KeyValuesState<'a> {
107 Borrowed(&'a [(Key<'a>, Value<'a>)]),
108 Owned(&'a [(KeyOwned, ValueOwned)]),
109}
110
111impl<'a> KeyValues<'a> {
112 pub fn len(&self) -> usize {
114 match self.0 {
115 KeyValuesState::Borrowed(p) => p.len(),
116 KeyValuesState::Owned(p) => p.len(),
117 }
118 }
119
120 pub fn is_empty(&self) -> bool {
122 match self.0 {
123 KeyValuesState::Borrowed(p) => p.is_empty(),
124 KeyValuesState::Owned(p) => p.is_empty(),
125 }
126 }
127
128 pub fn iter(&self) -> KeyValuesIter<'a> {
130 match &self.0 {
131 KeyValuesState::Borrowed(p) => KeyValuesIter(KeyValuesIterState::Borrowed(p.iter())),
132 KeyValuesState::Owned(p) => KeyValuesIter(KeyValuesIterState::Owned(p.iter())),
133 }
134 }
135
136 pub fn visit(&self, visitor: &mut dyn Visitor) -> Result<(), Error> {
138 for (k, v) in self.iter() {
139 visitor.visit(k, v)?;
140 }
141 Ok(())
142 }
143}
144
145impl fmt::Debug for KeyValues<'_> {
146 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147 f.debug_list().entries(self.iter()).finish()
148 }
149}
150
151impl Clone for KeyValues<'_> {
152 fn clone(&self) -> Self {
153 match &self.0 {
154 KeyValuesState::Borrowed(p) => KeyValues(KeyValuesState::Borrowed(p)),
155 KeyValuesState::Owned(p) => KeyValues(KeyValuesState::Owned(p)),
156 }
157 }
158}
159
160impl Default for KeyValues<'_> {
161 fn default() -> Self {
162 KeyValues(KeyValuesState::Borrowed(&[]))
163 }
164}
165
166impl<'a> IntoIterator for KeyValues<'a> {
167 type Item = (Key<'a>, Value<'a>);
168 type IntoIter = KeyValuesIter<'a>;
169
170 fn into_iter(self) -> Self::IntoIter {
171 self.iter()
172 }
173}
174
175impl<'a> From<&'a [(Key<'a>, Value<'a>)]> for KeyValues<'a> {
176 fn from(kvs: &'a [(Key<'a>, Value<'a>)]) -> Self {
177 Self(KeyValuesState::Borrowed(kvs))
178 }
179}
180
181impl<'a> From<&'a [(KeyOwned, ValueOwned)]> for KeyValues<'a> {
182 fn from(kvs: &'a [(KeyOwned, ValueOwned)]) -> Self {
183 Self(KeyValuesState::Owned(kvs))
184 }
185}
186
187pub struct KeyValuesIter<'a>(KeyValuesIterState<'a>);
189
190enum KeyValuesIterState<'a> {
191 Borrowed(slice::Iter<'a, (Key<'a>, Value<'a>)>),
192 Owned(slice::Iter<'a, (KeyOwned, ValueOwned)>),
193}
194
195impl<'a> Iterator for KeyValuesIter<'a> {
196 type Item = (Key<'a>, Value<'a>);
197
198 fn next(&mut self) -> Option<Self::Item> {
199 match &mut self.0 {
200 KeyValuesIterState::Borrowed(iter) => iter.next().map(|(k, v)| (k.clone(), v.clone())),
201 KeyValuesIterState::Owned(iter) => iter.next().map(|(k, v)| (k.by_ref(), v.by_ref())),
202 }
203 }
204
205 fn size_hint(&self) -> (usize, Option<usize>) {
206 match &self.0 {
207 KeyValuesIterState::Borrowed(iter) => iter.size_hint(),
208 KeyValuesIterState::Owned(iter) => iter.size_hint(),
209 }
210 }
211}