Skip to main content

nu_protocol/value/
record.rs

1//! Our insertion ordered map-type [`Record`]
2use std::{
3    iter::FusedIterator,
4    marker::PhantomData,
5    ops::{Deref, DerefMut, RangeBounds},
6};
7
8use crate::{
9    ShellError, Span, Value,
10    casing::{CaseInsensitive, CaseSensitive, CaseSensitivity, Casing, WrapCased},
11};
12
13use serde::{Deserialize, Serialize, de::Visitor, ser::SerializeMap};
14
15#[derive(Debug, Clone, Default, PartialEq)]
16pub struct Record {
17    inner: Vec<(String, Value)>,
18}
19
20/// A wrapper around [`Record`] that handles lookups. Whether the keys are compared case sensitively
21/// or not is controlled with the `Sensitivity` parameter.
22///
23/// It is never actually constructed as a value and only used as a reference to an existing [`Record`].
24#[repr(transparent)]
25pub struct CasedRecord<Sensitivity: CaseSensitivity>(Record, PhantomData<Sensitivity>);
26
27impl<Sensitivity: CaseSensitivity> CasedRecord<Sensitivity> {
28    #[inline]
29    const fn from_record(record: &Record) -> &Self {
30        // SAFETY: `CasedRecord` has the same memory layout as `Record`.
31        unsafe { &*(record as *const Record as *const Self) }
32    }
33
34    #[inline]
35    const fn from_record_mut(record: &mut Record) -> &mut Self {
36        // SAFETY: `CasedRecord` has the same memory layout as `Record`.
37        unsafe { &mut *(record as *mut Record as *mut Self) }
38    }
39
40    pub fn index_of(&self, col: impl AsRef<str>) -> Option<usize> {
41        let col = col.as_ref();
42        self.0.columns().rposition(|k| Sensitivity::eq(k, col))
43    }
44
45    pub fn contains(&self, col: impl AsRef<str>) -> bool {
46        self.index_of(col.as_ref()).is_some()
47    }
48
49    pub fn get(&self, col: impl AsRef<str>) -> Option<&Value> {
50        let index = self.index_of(col.as_ref())?;
51        Some(self.0.get_index(index)?.1)
52    }
53
54    pub fn get_mut(&mut self, col: impl AsRef<str>) -> Option<&mut Value> {
55        let index = self.index_of(col.as_ref())?;
56        Some(self.0.get_index_mut(index)?.1)
57    }
58
59    /// Remove single value by key and return it
60    pub fn remove(&mut self, col: impl AsRef<str>) -> Option<Value> {
61        let index = self.index_of(col.as_ref())?;
62        Some(self.0.remove_index(index))
63    }
64
65    /// Insert into the record, replacing preexisting value if found.
66    ///
67    /// Returns `Some(previous_value)` if found. Else `None`
68    pub fn insert<K>(&mut self, col: K, val: Value) -> Option<Value>
69    where
70        K: AsRef<str> + Into<String>,
71    {
72        if let Some(curr_val) = self.get_mut(col.as_ref()) {
73            Some(std::mem::replace(curr_val, val))
74        } else {
75            self.0.push(col, val);
76            None
77        }
78    }
79}
80
81impl<'a> WrapCased for &'a Record {
82    type Wrapper<S: CaseSensitivity> = &'a CasedRecord<S>;
83
84    #[inline]
85    fn case_sensitive(self) -> Self::Wrapper<CaseSensitive> {
86        CasedRecord::<CaseSensitive>::from_record(self)
87    }
88
89    #[inline]
90    fn case_insensitive(self) -> Self::Wrapper<CaseInsensitive> {
91        CasedRecord::<CaseInsensitive>::from_record(self)
92    }
93}
94
95impl<'a> WrapCased for &'a mut Record {
96    type Wrapper<S: CaseSensitivity> = &'a mut CasedRecord<S>;
97
98    #[inline]
99    fn case_sensitive(self) -> Self::Wrapper<CaseSensitive> {
100        CasedRecord::<CaseSensitive>::from_record_mut(self)
101    }
102
103    #[inline]
104    fn case_insensitive(self) -> Self::Wrapper<CaseInsensitive> {
105        CasedRecord::<CaseInsensitive>::from_record_mut(self)
106    }
107}
108
109impl AsRef<Record> for Record {
110    fn as_ref(&self) -> &Record {
111        self
112    }
113}
114
115impl AsMut<Record> for Record {
116    fn as_mut(&mut self) -> &mut Record {
117        self
118    }
119}
120
121impl Deref for Record {
122    type Target = CasedRecord<CaseSensitive>;
123
124    fn deref(&self) -> &Self::Target {
125        self.case_sensitive()
126    }
127}
128
129impl DerefMut for Record {
130    fn deref_mut(&mut self) -> &mut Self::Target {
131        self.case_sensitive()
132    }
133}
134
135/// A wrapper around [`Record`] that affects whether key comparisons are case sensitive or not.
136///
137/// Implements commonly used methods of [`Record`].
138pub struct DynCasedRecord<R> {
139    record: R,
140    casing: Casing,
141}
142
143impl Clone for DynCasedRecord<&Record> {
144    fn clone(&self) -> Self {
145        *self
146    }
147}
148
149impl Copy for DynCasedRecord<&Record> {}
150
151impl<'a> DynCasedRecord<&'a Record> {
152    pub fn index_of(self, col: impl AsRef<str>) -> Option<usize> {
153        match self.casing {
154            Casing::Sensitive => self.record.case_sensitive().index_of(col.as_ref()),
155            Casing::Insensitive => self.record.case_insensitive().index_of(col.as_ref()),
156        }
157    }
158
159    pub fn contains(self, col: impl AsRef<str>) -> bool {
160        self.get(col.as_ref()).is_some()
161    }
162
163    pub fn get(self, col: impl AsRef<str>) -> Option<&'a Value> {
164        match self.casing {
165            Casing::Sensitive => self.record.case_sensitive().get(col.as_ref()),
166            Casing::Insensitive => self.record.case_insensitive().get(col.as_ref()),
167        }
168    }
169}
170
171impl<'a> DynCasedRecord<&'a mut Record> {
172    /// Explicit reborrowing. See [Self::reborrow_mut()]
173    pub fn reborrow(&self) -> DynCasedRecord<&Record> {
174        DynCasedRecord {
175            record: &*self.record,
176            casing: self.casing,
177        }
178    }
179
180    /// Explicit reborrowing. Using this before methods that receive `self` is necessary to avoid
181    /// consuming the `DynCasedRecord` instance.
182    ///
183    /// ```
184    /// use nu_protocol::{record, record::{Record, DynCasedRecord}, Value, casing::Casing};
185    ///
186    /// let mut rec = record!{
187    ///     "A" => Value::test_nothing(),
188    ///     "B" => Value::test_int(42),
189    ///     "C" => Value::test_nothing(),
190    ///     "D" => Value::test_int(42),
191    /// };
192    /// let mut cased_rec: DynCasedRecord<&mut Record> = rec.cased_mut(Casing::Insensitive);
193    /// ```
194    ///
195    /// The following will fail to compile:
196    ///
197    /// ```compile_fail
198    /// # use nu_protocol::{record, record::{Record, DynCasedRecord}, Value, casing::Casing};
199    /// # let mut rec = record!{};
200    /// # let mut cased_rec: DynCasedRecord<&mut Record> = rec.cased_mut(Casing::Insensitive);
201    /// let a = cased_rec.get_mut("a");
202    /// let b = cased_rec.get_mut("b");
203    /// ```
204    ///
205    /// This is due to the fact `.get_mut()` receives `self`[^self] _by value_, which limits its use to
206    /// just once, unless we construct a new `DynCasedRecord`.
207    ///
208    /// [^self]: Receiving `&mut self` works, but has an undesirable effect on the return value's
209    /// lifetime. With `Self == &'wrapper mut DynCasedRecord<&'source mut Record>`, return value's
210    /// lifetime will be `'wrapper` rather than `'source`.
211    ///
212    /// We can create a new `DynCasedRecord<&mut Record>` from an existing one even though `&mut T` is
213    /// not [`Copy`]. This is accomplished with [reborrowing] which happens implicitly with native
214    /// references. Reborrowing also happens to be a tragically under documented feature of rust.
215    ///
216    /// Though there isn't a trait for it yet, it's possible and simple to implement, it just has
217    /// to be called explicitly:
218    ///
219    /// ```
220    /// # use nu_protocol::{record, record::{Record, DynCasedRecord}, Value, casing::Casing};
221    /// # let mut rec = record!{};
222    /// # let mut cased_rec: DynCasedRecord<&mut Record> = rec.cased_mut(Casing::Insensitive);
223    /// let a = cased_rec.reborrow_mut().get_mut("a");
224    /// let b = cased_rec.reborrow_mut().get_mut("b");
225    /// ```
226    ///
227    /// [reborrowing]: https://quinedot.github.io/rust-learning/st-reborrow.html
228    pub fn reborrow_mut(&mut self) -> DynCasedRecord<&mut Record> {
229        DynCasedRecord {
230            record: &mut *self.record,
231            casing: self.casing,
232        }
233    }
234
235    pub fn get_mut(self, col: impl AsRef<str>) -> Option<&'a mut Value> {
236        match self.casing {
237            Casing::Sensitive => self.record.case_sensitive().get_mut(col.as_ref()),
238            Casing::Insensitive => self.record.case_insensitive().get_mut(col.as_ref()),
239        }
240    }
241
242    pub fn remove(self, col: impl AsRef<str>) -> Option<Value> {
243        match self.casing {
244            Casing::Sensitive => self.record.case_sensitive().remove(col.as_ref()),
245            Casing::Insensitive => self.record.case_insensitive().remove(col.as_ref()),
246        }
247    }
248
249    /// Insert into the record, replacing preexisting value if found.
250    ///
251    /// Returns `Some(previous_value)` if found. Else `None`
252    pub fn insert<K>(self, col: K, val: Value) -> Option<Value>
253    where
254        K: AsRef<str> + Into<String>,
255    {
256        match self.casing {
257            Casing::Sensitive => self.record.case_sensitive().insert(col.as_ref(), val),
258            Casing::Insensitive => self.record.case_insensitive().insert(col.as_ref(), val),
259        }
260    }
261}
262
263impl Record {
264    pub fn new() -> Self {
265        Self::default()
266    }
267
268    pub fn with_capacity(capacity: usize) -> Self {
269        Self {
270            inner: Vec::with_capacity(capacity),
271        }
272    }
273
274    /// Returns an estimate of the memory size used by this Record in bytes
275    pub fn memory_size(&self) -> usize {
276        std::mem::size_of::<Self>()
277            + self
278                .inner
279                .iter()
280                .map(|(k, v)| k.capacity() + v.memory_size())
281                .sum::<usize>()
282    }
283
284    pub fn cased(&self, casing: Casing) -> DynCasedRecord<&Record> {
285        DynCasedRecord {
286            record: self,
287            casing,
288        }
289    }
290
291    pub fn cased_mut(&mut self, casing: Casing) -> DynCasedRecord<&mut Record> {
292        DynCasedRecord {
293            record: self,
294            casing,
295        }
296    }
297
298    /// Create a [`Record`] from a `Vec` of columns and a `Vec` of [`Value`]s
299    ///
300    /// Returns an error if `cols` and `vals` have different lengths.
301    ///
302    /// For perf reasons, this will not validate the rest of the record assumptions:
303    /// - unique keys
304    pub fn from_raw_cols_vals(
305        cols: Vec<String>,
306        vals: Vec<Value>,
307        input_span: Span,
308        creation_site_span: Span,
309    ) -> Result<Self, ShellError> {
310        if cols.len() == vals.len() {
311            let inner = cols.into_iter().zip(vals).collect();
312            Ok(Self { inner })
313        } else {
314            Err(ShellError::RecordColsValsMismatch {
315                bad_value: input_span,
316                creation_site: creation_site_span,
317            })
318        }
319    }
320
321    pub fn iter(&self) -> Iter<'_> {
322        self.into_iter()
323    }
324
325    pub fn iter_mut(&mut self) -> IterMut<'_> {
326        self.into_iter()
327    }
328
329    pub fn is_empty(&self) -> bool {
330        self.inner.is_empty()
331    }
332
333    pub fn len(&self) -> usize {
334        self.inner.len()
335    }
336
337    /// Naive push to the end of the datastructure.
338    ///
339    /// <div class="warning">
340    /// May duplicate data!
341    ///
342    /// Consider using [`CasedRecord::insert`] or [`DynCasedRecord::insert`] instead.
343    /// </div>
344    pub fn push(&mut self, col: impl Into<String>, val: Value) {
345        self.inner.push((col.into(), val));
346    }
347
348    pub fn get_index(&self, idx: usize) -> Option<(&String, &Value)> {
349        self.inner.get(idx).map(|(col, val): &(_, _)| (col, val))
350    }
351
352    pub fn get_index_mut(&mut self, idx: usize) -> Option<(&mut String, &mut Value)> {
353        self.inner.get_mut(idx).map(|(col, val)| (col, val))
354    }
355
356    /// Remove single value by index
357    fn remove_index(&mut self, index: usize) -> Value {
358        self.inner.remove(index).1
359    }
360
361    /// Remove elements in-place that do not satisfy `keep`
362    ///
363    /// ```rust
364    /// use nu_protocol::{record, Value};
365    ///
366    /// let mut rec = record!(
367    ///     "a" => Value::test_nothing(),
368    ///     "b" => Value::test_int(42),
369    ///     "c" => Value::test_nothing(),
370    ///     "d" => Value::test_int(42),
371    /// );
372    /// rec.retain(|_k, val| !val.is_nothing());
373    /// let mut iter_rec = rec.columns();
374    /// assert_eq!(iter_rec.next().map(String::as_str), Some("b"));
375    /// assert_eq!(iter_rec.next().map(String::as_str), Some("d"));
376    /// assert_eq!(iter_rec.next(), None);
377    /// ```
378    pub fn retain<F>(&mut self, mut keep: F)
379    where
380        F: FnMut(&str, &Value) -> bool,
381    {
382        self.retain_mut(|k, v| keep(k, v));
383    }
384
385    /// Remove elements in-place that do not satisfy `keep` while allowing mutation of the value.
386    ///
387    /// This can for example be used to recursively prune nested records.
388    ///
389    /// ```rust
390    /// use nu_protocol::{record, Record, Value};
391    ///
392    /// fn remove_foo_recursively(val: &mut Value) {
393    ///     if let Value::Record {val, ..} = val {
394    ///         val.to_mut().retain_mut(keep_non_foo);
395    ///     }
396    /// }
397    ///
398    /// fn keep_non_foo(k: &str, v: &mut Value) -> bool {
399    ///     if k == "foo" {
400    ///         return false;
401    ///     }
402    ///     remove_foo_recursively(v);
403    ///     true
404    /// }
405    ///
406    /// let mut test = Value::test_record(record!(
407    ///     "foo" => Value::test_nothing(),
408    ///     "bar" => Value::test_record(record!(
409    ///         "foo" => Value::test_nothing(),
410    ///         "baz" => Value::test_nothing(),
411    ///         ))
412    ///     ));
413    ///
414    /// remove_foo_recursively(&mut test);
415    /// let expected = Value::test_record(record!(
416    ///     "bar" => Value::test_record(record!(
417    ///         "baz" => Value::test_nothing(),
418    ///         ))
419    ///     ));
420    /// assert_eq!(test, expected);
421    /// ```
422    pub fn retain_mut<F>(&mut self, mut keep: F)
423    where
424        F: FnMut(&str, &mut Value) -> bool,
425    {
426        self.inner.retain_mut(|(col, val)| keep(col, val));
427    }
428
429    /// Truncate record to the first `len` elements.
430    ///
431    /// `len > self.len()` will be ignored
432    ///
433    /// ```rust
434    /// use nu_protocol::{record, Value};
435    ///
436    /// let mut rec = record!(
437    ///     "a" => Value::test_nothing(),
438    ///     "b" => Value::test_int(42),
439    ///     "c" => Value::test_nothing(),
440    ///     "d" => Value::test_int(42),
441    /// );
442    /// rec.truncate(42); // this is fine
443    /// assert_eq!(rec.columns().map(String::as_str).collect::<String>(), "abcd");
444    /// rec.truncate(2); // truncate
445    /// assert_eq!(rec.columns().map(String::as_str).collect::<String>(), "ab");
446    /// rec.truncate(0); // clear the record
447    /// assert_eq!(rec.len(), 0);
448    /// ```
449    pub fn truncate(&mut self, len: usize) {
450        self.inner.truncate(len);
451    }
452
453    pub fn truncate_front(&mut self, len: usize) {
454        if self.len() < len {
455            return;
456        }
457        let drop = self.len() - len;
458        self.inner.drain(..drop);
459    }
460
461    pub fn columns(&self) -> Columns<'_> {
462        Columns {
463            iter: self.inner.iter(),
464        }
465    }
466
467    pub fn into_columns(self) -> IntoColumns {
468        IntoColumns {
469            iter: self.inner.into_iter(),
470        }
471    }
472
473    pub fn values(&self) -> Values<'_> {
474        Values {
475            iter: self.inner.iter(),
476        }
477    }
478
479    pub fn into_values(self) -> IntoValues {
480        IntoValues {
481            iter: self.inner.into_iter(),
482        }
483    }
484
485    /// Obtain an iterator to remove elements in `range`
486    ///
487    /// Elements not consumed from the iterator will be dropped
488    ///
489    /// ```rust
490    /// use nu_protocol::{record, Value};
491    ///
492    /// let mut rec = record!(
493    ///     "a" => Value::test_nothing(),
494    ///     "b" => Value::test_int(42),
495    ///     "c" => Value::test_string("foo"),
496    /// );
497    /// {
498    ///     let mut drainer = rec.drain(1..);
499    ///     assert_eq!(drainer.next(), Some(("b".into(), Value::test_int(42))));
500    ///     // Dropping the `Drain`
501    /// }
502    /// let mut rec_iter = rec.into_iter();
503    /// assert_eq!(rec_iter.next(), Some(("a".into(), Value::test_nothing())));
504    /// assert_eq!(rec_iter.next(), None);
505    /// ```
506    pub fn drain<R>(&mut self, range: R) -> Drain<'_>
507    where
508        R: RangeBounds<usize> + Clone,
509    {
510        Drain {
511            iter: self.inner.drain(range),
512        }
513    }
514
515    /// Sort the record by its columns.
516    ///
517    /// ```rust
518    /// use nu_protocol::{record, Value};
519    ///
520    /// let mut rec = record!(
521    ///     "c" => Value::test_string("foo"),
522    ///     "b" => Value::test_int(42),
523    ///     "a" => Value::test_nothing(),
524    /// );
525    ///
526    /// rec.sort_cols();
527    ///
528    /// assert_eq!(
529    ///     Value::test_record(rec),
530    ///     Value::test_record(record!(
531    ///         "a" => Value::test_nothing(),
532    ///         "b" => Value::test_int(42),
533    ///         "c" => Value::test_string("foo"),
534    ///     ))
535    /// );
536    /// ```
537    pub fn sort_cols(&mut self) {
538        self.inner.sort_by(|(k1, _), (k2, _)| k1.cmp(k2))
539    }
540}
541
542impl Serialize for Record {
543    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
544    where
545        S: serde::Serializer,
546    {
547        let mut map = serializer.serialize_map(Some(self.len()))?;
548        for (k, v) in self {
549            map.serialize_entry(k, v)?;
550        }
551        map.end()
552    }
553}
554
555impl<'de> Deserialize<'de> for Record {
556    /// Special deserialization implementation that turns a map-pattern into a [`Record`]
557    ///
558    /// Denies duplicate keys
559    ///
560    /// ```rust
561    /// use serde_json::{from_str, Result};
562    /// use nu_protocol::{Record, Value, record};
563    ///
564    /// // A `Record` in json is a Record with a packed `Value`
565    /// // The `Value` record has a single key indicating its type and the inner record describing
566    /// // its representation of value and the associated `Span`
567    /// let ok = r#"{"a": {"Int": {"val": 42, "span": {"start": 0, "end": 0}}},
568    ///              "b": {"Int": {"val": 37, "span": {"start": 0, "end": 0}}}}"#;
569    /// let ok_rec: Record = from_str(ok).unwrap();
570    /// assert_eq!(Value::test_record(ok_rec),
571    ///            Value::test_record(record!{"a" => Value::test_int(42),
572    ///                                       "b" => Value::test_int(37)}));
573    /// // A repeated key will lead to a deserialization error
574    /// let bad = r#"{"a": {"Int": {"val": 42, "span": {"start": 0, "end": 0}}},
575    ///               "a": {"Int": {"val": 37, "span": {"start": 0, "end": 0}}}}"#;
576    /// let bad_rec: Result<Record> = from_str(bad);
577    /// assert!(bad_rec.is_err());
578    /// ```
579    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
580    where
581        D: serde::Deserializer<'de>,
582    {
583        deserializer.deserialize_map(RecordVisitor)
584    }
585}
586
587struct RecordVisitor;
588
589impl<'de> Visitor<'de> for RecordVisitor {
590    type Value = Record;
591
592    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
593        formatter.write_str("a nushell `Record` mapping string keys/columns to nushell `Value`")
594    }
595
596    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
597    where
598        A: serde::de::MapAccess<'de>,
599    {
600        let mut record = Record::with_capacity(map.size_hint().unwrap_or(0));
601
602        while let Some((key, value)) = map.next_entry::<String, Value>()? {
603            if record.insert(key, value).is_some() {
604                return Err(serde::de::Error::custom(
605                    "invalid entry, duplicate keys are not allowed for `Record`",
606                ));
607            }
608        }
609
610        Ok(record)
611    }
612}
613
614impl FromIterator<(String, Value)> for Record {
615    fn from_iter<T: IntoIterator<Item = (String, Value)>>(iter: T) -> Self {
616        // TODO: should this check for duplicate keys/columns?
617        Self {
618            inner: iter.into_iter().collect(),
619        }
620    }
621}
622
623impl Extend<(String, Value)> for Record {
624    fn extend<T: IntoIterator<Item = (String, Value)>>(&mut self, iter: T) {
625        for (k, v) in iter {
626            // TODO: should this .insert with a check?
627            self.push(k, v)
628        }
629    }
630}
631
632pub struct IntoIter {
633    iter: std::vec::IntoIter<(String, Value)>,
634}
635
636impl Iterator for IntoIter {
637    type Item = (String, Value);
638
639    fn next(&mut self) -> Option<Self::Item> {
640        self.iter.next()
641    }
642
643    fn size_hint(&self) -> (usize, Option<usize>) {
644        self.iter.size_hint()
645    }
646}
647
648impl DoubleEndedIterator for IntoIter {
649    fn next_back(&mut self) -> Option<Self::Item> {
650        self.iter.next_back()
651    }
652}
653
654impl ExactSizeIterator for IntoIter {
655    fn len(&self) -> usize {
656        self.iter.len()
657    }
658}
659
660impl FusedIterator for IntoIter {}
661
662impl IntoIterator for Record {
663    type Item = (String, Value);
664
665    type IntoIter = IntoIter;
666
667    fn into_iter(self) -> Self::IntoIter {
668        IntoIter {
669            iter: self.inner.into_iter(),
670        }
671    }
672}
673
674pub struct Iter<'a> {
675    iter: std::slice::Iter<'a, (String, Value)>,
676}
677
678impl<'a> Iterator for Iter<'a> {
679    type Item = (&'a String, &'a Value);
680
681    fn next(&mut self) -> Option<Self::Item> {
682        self.iter.next().map(|(col, val): &(_, _)| (col, val))
683    }
684
685    fn size_hint(&self) -> (usize, Option<usize>) {
686        self.iter.size_hint()
687    }
688}
689
690impl DoubleEndedIterator for Iter<'_> {
691    fn next_back(&mut self) -> Option<Self::Item> {
692        self.iter.next_back().map(|(col, val): &(_, _)| (col, val))
693    }
694}
695
696impl ExactSizeIterator for Iter<'_> {
697    fn len(&self) -> usize {
698        self.iter.len()
699    }
700}
701
702impl FusedIterator for Iter<'_> {}
703
704impl<'a> IntoIterator for &'a Record {
705    type Item = (&'a String, &'a Value);
706
707    type IntoIter = Iter<'a>;
708
709    fn into_iter(self) -> Self::IntoIter {
710        Iter {
711            iter: self.inner.iter(),
712        }
713    }
714}
715
716pub struct IterMut<'a> {
717    iter: std::slice::IterMut<'a, (String, Value)>,
718}
719
720impl<'a> Iterator for IterMut<'a> {
721    type Item = (&'a String, &'a mut Value);
722
723    fn next(&mut self) -> Option<Self::Item> {
724        self.iter.next().map(|(col, val)| (&*col, val))
725    }
726
727    fn size_hint(&self) -> (usize, Option<usize>) {
728        self.iter.size_hint()
729    }
730}
731
732impl DoubleEndedIterator for IterMut<'_> {
733    fn next_back(&mut self) -> Option<Self::Item> {
734        self.iter.next_back().map(|(col, val)| (&*col, val))
735    }
736}
737
738impl ExactSizeIterator for IterMut<'_> {
739    fn len(&self) -> usize {
740        self.iter.len()
741    }
742}
743
744impl FusedIterator for IterMut<'_> {}
745
746impl<'a> IntoIterator for &'a mut Record {
747    type Item = (&'a String, &'a mut Value);
748
749    type IntoIter = IterMut<'a>;
750
751    fn into_iter(self) -> Self::IntoIter {
752        IterMut {
753            iter: self.inner.iter_mut(),
754        }
755    }
756}
757
758pub struct Columns<'a> {
759    iter: std::slice::Iter<'a, (String, Value)>,
760}
761
762impl<'a> Iterator for Columns<'a> {
763    type Item = &'a String;
764
765    fn next(&mut self) -> Option<Self::Item> {
766        self.iter.next().map(|(col, _)| col)
767    }
768
769    fn size_hint(&self) -> (usize, Option<usize>) {
770        self.iter.size_hint()
771    }
772}
773
774impl DoubleEndedIterator for Columns<'_> {
775    fn next_back(&mut self) -> Option<Self::Item> {
776        self.iter.next_back().map(|(col, _)| col)
777    }
778}
779
780impl ExactSizeIterator for Columns<'_> {
781    fn len(&self) -> usize {
782        self.iter.len()
783    }
784}
785
786impl FusedIterator for Columns<'_> {}
787
788pub struct IntoColumns {
789    iter: std::vec::IntoIter<(String, Value)>,
790}
791
792impl Iterator for IntoColumns {
793    type Item = String;
794
795    fn next(&mut self) -> Option<Self::Item> {
796        self.iter.next().map(|(col, _)| col)
797    }
798
799    fn size_hint(&self) -> (usize, Option<usize>) {
800        self.iter.size_hint()
801    }
802}
803
804impl DoubleEndedIterator for IntoColumns {
805    fn next_back(&mut self) -> Option<Self::Item> {
806        self.iter.next_back().map(|(col, _)| col)
807    }
808}
809
810impl ExactSizeIterator for IntoColumns {
811    fn len(&self) -> usize {
812        self.iter.len()
813    }
814}
815
816impl FusedIterator for IntoColumns {}
817
818pub struct Values<'a> {
819    iter: std::slice::Iter<'a, (String, Value)>,
820}
821
822impl<'a> Iterator for Values<'a> {
823    type Item = &'a Value;
824
825    fn next(&mut self) -> Option<Self::Item> {
826        self.iter.next().map(|(_, val)| val)
827    }
828
829    fn size_hint(&self) -> (usize, Option<usize>) {
830        self.iter.size_hint()
831    }
832}
833
834impl DoubleEndedIterator for Values<'_> {
835    fn next_back(&mut self) -> Option<Self::Item> {
836        self.iter.next_back().map(|(_, val)| val)
837    }
838}
839
840impl ExactSizeIterator for Values<'_> {
841    fn len(&self) -> usize {
842        self.iter.len()
843    }
844}
845
846impl FusedIterator for Values<'_> {}
847
848pub struct IntoValues {
849    iter: std::vec::IntoIter<(String, Value)>,
850}
851
852impl Iterator for IntoValues {
853    type Item = Value;
854
855    fn next(&mut self) -> Option<Self::Item> {
856        self.iter.next().map(|(_, val)| val)
857    }
858
859    fn size_hint(&self) -> (usize, Option<usize>) {
860        self.iter.size_hint()
861    }
862}
863
864impl DoubleEndedIterator for IntoValues {
865    fn next_back(&mut self) -> Option<Self::Item> {
866        self.iter.next_back().map(|(_, val)| val)
867    }
868}
869
870impl ExactSizeIterator for IntoValues {
871    fn len(&self) -> usize {
872        self.iter.len()
873    }
874}
875
876impl FusedIterator for IntoValues {}
877
878pub struct Drain<'a> {
879    iter: std::vec::Drain<'a, (String, Value)>,
880}
881
882impl Iterator for Drain<'_> {
883    type Item = (String, Value);
884
885    fn next(&mut self) -> Option<Self::Item> {
886        self.iter.next()
887    }
888
889    fn size_hint(&self) -> (usize, Option<usize>) {
890        self.iter.size_hint()
891    }
892}
893
894impl DoubleEndedIterator for Drain<'_> {
895    fn next_back(&mut self) -> Option<Self::Item> {
896        self.iter.next_back()
897    }
898}
899
900impl ExactSizeIterator for Drain<'_> {
901    fn len(&self) -> usize {
902        self.iter.len()
903    }
904}
905
906impl FusedIterator for Drain<'_> {}
907
908#[macro_export]
909macro_rules! record {
910    // The macro only compiles if the number of columns equals the number of values,
911    // so it's safe to call `unwrap` below.
912    {$($col:expr => $val:expr),+ $(,)?} => {
913        $crate::Record::from_raw_cols_vals(
914            ::std::vec![$($col.into(),)+],
915            ::std::vec![$($val,)+],
916            $crate::Span::unknown(),
917            $crate::Span::unknown(),
918        ).unwrap()
919    };
920    {} => {
921        $crate::Record::new()
922    };
923}