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 columns(&self) -> Columns<'_> {
454        Columns {
455            iter: self.inner.iter(),
456        }
457    }
458
459    pub fn into_columns(self) -> IntoColumns {
460        IntoColumns {
461            iter: self.inner.into_iter(),
462        }
463    }
464
465    pub fn values(&self) -> Values<'_> {
466        Values {
467            iter: self.inner.iter(),
468        }
469    }
470
471    pub fn into_values(self) -> IntoValues {
472        IntoValues {
473            iter: self.inner.into_iter(),
474        }
475    }
476
477    /// Obtain an iterator to remove elements in `range`
478    ///
479    /// Elements not consumed from the iterator will be dropped
480    ///
481    /// ```rust
482    /// use nu_protocol::{record, Value};
483    ///
484    /// let mut rec = record!(
485    ///     "a" => Value::test_nothing(),
486    ///     "b" => Value::test_int(42),
487    ///     "c" => Value::test_string("foo"),
488    /// );
489    /// {
490    ///     let mut drainer = rec.drain(1..);
491    ///     assert_eq!(drainer.next(), Some(("b".into(), Value::test_int(42))));
492    ///     // Dropping the `Drain`
493    /// }
494    /// let mut rec_iter = rec.into_iter();
495    /// assert_eq!(rec_iter.next(), Some(("a".into(), Value::test_nothing())));
496    /// assert_eq!(rec_iter.next(), None);
497    /// ```
498    pub fn drain<R>(&mut self, range: R) -> Drain<'_>
499    where
500        R: RangeBounds<usize> + Clone,
501    {
502        Drain {
503            iter: self.inner.drain(range),
504        }
505    }
506
507    /// Sort the record by its columns.
508    ///
509    /// ```rust
510    /// use nu_protocol::{record, Value};
511    ///
512    /// let mut rec = record!(
513    ///     "c" => Value::test_string("foo"),
514    ///     "b" => Value::test_int(42),
515    ///     "a" => Value::test_nothing(),
516    /// );
517    ///
518    /// rec.sort_cols();
519    ///
520    /// assert_eq!(
521    ///     Value::test_record(rec),
522    ///     Value::test_record(record!(
523    ///         "a" => Value::test_nothing(),
524    ///         "b" => Value::test_int(42),
525    ///         "c" => Value::test_string("foo"),
526    ///     ))
527    /// );
528    /// ```
529    pub fn sort_cols(&mut self) {
530        self.inner.sort_by(|(k1, _), (k2, _)| k1.cmp(k2))
531    }
532}
533
534impl Serialize for Record {
535    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
536    where
537        S: serde::Serializer,
538    {
539        let mut map = serializer.serialize_map(Some(self.len()))?;
540        for (k, v) in self {
541            map.serialize_entry(k, v)?;
542        }
543        map.end()
544    }
545}
546
547impl<'de> Deserialize<'de> for Record {
548    /// Special deserialization implementation that turns a map-pattern into a [`Record`]
549    ///
550    /// Denies duplicate keys
551    ///
552    /// ```rust
553    /// use serde_json::{from_str, Result};
554    /// use nu_protocol::{Record, Value, record};
555    ///
556    /// // A `Record` in json is a Record with a packed `Value`
557    /// // The `Value` record has a single key indicating its type and the inner record describing
558    /// // its representation of value and the associated `Span`
559    /// let ok = r#"{"a": {"Int": {"val": 42, "span": {"start": 0, "end": 0}}},
560    ///              "b": {"Int": {"val": 37, "span": {"start": 0, "end": 0}}}}"#;
561    /// let ok_rec: Record = from_str(ok).unwrap();
562    /// assert_eq!(Value::test_record(ok_rec),
563    ///            Value::test_record(record!{"a" => Value::test_int(42),
564    ///                                       "b" => Value::test_int(37)}));
565    /// // A repeated key will lead to a deserialization error
566    /// let bad = r#"{"a": {"Int": {"val": 42, "span": {"start": 0, "end": 0}}},
567    ///               "a": {"Int": {"val": 37, "span": {"start": 0, "end": 0}}}}"#;
568    /// let bad_rec: Result<Record> = from_str(bad);
569    /// assert!(bad_rec.is_err());
570    /// ```
571    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
572    where
573        D: serde::Deserializer<'de>,
574    {
575        deserializer.deserialize_map(RecordVisitor)
576    }
577}
578
579struct RecordVisitor;
580
581impl<'de> Visitor<'de> for RecordVisitor {
582    type Value = Record;
583
584    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
585        formatter.write_str("a nushell `Record` mapping string keys/columns to nushell `Value`")
586    }
587
588    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
589    where
590        A: serde::de::MapAccess<'de>,
591    {
592        let mut record = Record::with_capacity(map.size_hint().unwrap_or(0));
593
594        while let Some((key, value)) = map.next_entry::<String, Value>()? {
595            if record.insert(key, value).is_some() {
596                return Err(serde::de::Error::custom(
597                    "invalid entry, duplicate keys are not allowed for `Record`",
598                ));
599            }
600        }
601
602        Ok(record)
603    }
604}
605
606impl FromIterator<(String, Value)> for Record {
607    fn from_iter<T: IntoIterator<Item = (String, Value)>>(iter: T) -> Self {
608        // TODO: should this check for duplicate keys/columns?
609        Self {
610            inner: iter.into_iter().collect(),
611        }
612    }
613}
614
615impl Extend<(String, Value)> for Record {
616    fn extend<T: IntoIterator<Item = (String, Value)>>(&mut self, iter: T) {
617        for (k, v) in iter {
618            // TODO: should this .insert with a check?
619            self.push(k, v)
620        }
621    }
622}
623
624pub struct IntoIter {
625    iter: std::vec::IntoIter<(String, Value)>,
626}
627
628impl Iterator for IntoIter {
629    type Item = (String, Value);
630
631    fn next(&mut self) -> Option<Self::Item> {
632        self.iter.next()
633    }
634
635    fn size_hint(&self) -> (usize, Option<usize>) {
636        self.iter.size_hint()
637    }
638}
639
640impl DoubleEndedIterator for IntoIter {
641    fn next_back(&mut self) -> Option<Self::Item> {
642        self.iter.next_back()
643    }
644}
645
646impl ExactSizeIterator for IntoIter {
647    fn len(&self) -> usize {
648        self.iter.len()
649    }
650}
651
652impl FusedIterator for IntoIter {}
653
654impl IntoIterator for Record {
655    type Item = (String, Value);
656
657    type IntoIter = IntoIter;
658
659    fn into_iter(self) -> Self::IntoIter {
660        IntoIter {
661            iter: self.inner.into_iter(),
662        }
663    }
664}
665
666pub struct Iter<'a> {
667    iter: std::slice::Iter<'a, (String, Value)>,
668}
669
670impl<'a> Iterator for Iter<'a> {
671    type Item = (&'a String, &'a Value);
672
673    fn next(&mut self) -> Option<Self::Item> {
674        self.iter.next().map(|(col, val): &(_, _)| (col, val))
675    }
676
677    fn size_hint(&self) -> (usize, Option<usize>) {
678        self.iter.size_hint()
679    }
680}
681
682impl DoubleEndedIterator for Iter<'_> {
683    fn next_back(&mut self) -> Option<Self::Item> {
684        self.iter.next_back().map(|(col, val): &(_, _)| (col, val))
685    }
686}
687
688impl ExactSizeIterator for Iter<'_> {
689    fn len(&self) -> usize {
690        self.iter.len()
691    }
692}
693
694impl FusedIterator for Iter<'_> {}
695
696impl<'a> IntoIterator for &'a Record {
697    type Item = (&'a String, &'a Value);
698
699    type IntoIter = Iter<'a>;
700
701    fn into_iter(self) -> Self::IntoIter {
702        Iter {
703            iter: self.inner.iter(),
704        }
705    }
706}
707
708pub struct IterMut<'a> {
709    iter: std::slice::IterMut<'a, (String, Value)>,
710}
711
712impl<'a> Iterator for IterMut<'a> {
713    type Item = (&'a String, &'a mut Value);
714
715    fn next(&mut self) -> Option<Self::Item> {
716        self.iter.next().map(|(col, val)| (&*col, val))
717    }
718
719    fn size_hint(&self) -> (usize, Option<usize>) {
720        self.iter.size_hint()
721    }
722}
723
724impl DoubleEndedIterator for IterMut<'_> {
725    fn next_back(&mut self) -> Option<Self::Item> {
726        self.iter.next_back().map(|(col, val)| (&*col, val))
727    }
728}
729
730impl ExactSizeIterator for IterMut<'_> {
731    fn len(&self) -> usize {
732        self.iter.len()
733    }
734}
735
736impl FusedIterator for IterMut<'_> {}
737
738impl<'a> IntoIterator for &'a mut Record {
739    type Item = (&'a String, &'a mut Value);
740
741    type IntoIter = IterMut<'a>;
742
743    fn into_iter(self) -> Self::IntoIter {
744        IterMut {
745            iter: self.inner.iter_mut(),
746        }
747    }
748}
749
750pub struct Columns<'a> {
751    iter: std::slice::Iter<'a, (String, Value)>,
752}
753
754impl<'a> Iterator for Columns<'a> {
755    type Item = &'a String;
756
757    fn next(&mut self) -> Option<Self::Item> {
758        self.iter.next().map(|(col, _)| col)
759    }
760
761    fn size_hint(&self) -> (usize, Option<usize>) {
762        self.iter.size_hint()
763    }
764}
765
766impl DoubleEndedIterator for Columns<'_> {
767    fn next_back(&mut self) -> Option<Self::Item> {
768        self.iter.next_back().map(|(col, _)| col)
769    }
770}
771
772impl ExactSizeIterator for Columns<'_> {
773    fn len(&self) -> usize {
774        self.iter.len()
775    }
776}
777
778impl FusedIterator for Columns<'_> {}
779
780pub struct IntoColumns {
781    iter: std::vec::IntoIter<(String, Value)>,
782}
783
784impl Iterator for IntoColumns {
785    type Item = String;
786
787    fn next(&mut self) -> Option<Self::Item> {
788        self.iter.next().map(|(col, _)| col)
789    }
790
791    fn size_hint(&self) -> (usize, Option<usize>) {
792        self.iter.size_hint()
793    }
794}
795
796impl DoubleEndedIterator for IntoColumns {
797    fn next_back(&mut self) -> Option<Self::Item> {
798        self.iter.next_back().map(|(col, _)| col)
799    }
800}
801
802impl ExactSizeIterator for IntoColumns {
803    fn len(&self) -> usize {
804        self.iter.len()
805    }
806}
807
808impl FusedIterator for IntoColumns {}
809
810pub struct Values<'a> {
811    iter: std::slice::Iter<'a, (String, Value)>,
812}
813
814impl<'a> Iterator for Values<'a> {
815    type Item = &'a Value;
816
817    fn next(&mut self) -> Option<Self::Item> {
818        self.iter.next().map(|(_, val)| val)
819    }
820
821    fn size_hint(&self) -> (usize, Option<usize>) {
822        self.iter.size_hint()
823    }
824}
825
826impl DoubleEndedIterator for Values<'_> {
827    fn next_back(&mut self) -> Option<Self::Item> {
828        self.iter.next_back().map(|(_, val)| val)
829    }
830}
831
832impl ExactSizeIterator for Values<'_> {
833    fn len(&self) -> usize {
834        self.iter.len()
835    }
836}
837
838impl FusedIterator for Values<'_> {}
839
840pub struct IntoValues {
841    iter: std::vec::IntoIter<(String, Value)>,
842}
843
844impl Iterator for IntoValues {
845    type Item = Value;
846
847    fn next(&mut self) -> Option<Self::Item> {
848        self.iter.next().map(|(_, val)| val)
849    }
850
851    fn size_hint(&self) -> (usize, Option<usize>) {
852        self.iter.size_hint()
853    }
854}
855
856impl DoubleEndedIterator for IntoValues {
857    fn next_back(&mut self) -> Option<Self::Item> {
858        self.iter.next_back().map(|(_, val)| val)
859    }
860}
861
862impl ExactSizeIterator for IntoValues {
863    fn len(&self) -> usize {
864        self.iter.len()
865    }
866}
867
868impl FusedIterator for IntoValues {}
869
870pub struct Drain<'a> {
871    iter: std::vec::Drain<'a, (String, Value)>,
872}
873
874impl Iterator for Drain<'_> {
875    type Item = (String, Value);
876
877    fn next(&mut self) -> Option<Self::Item> {
878        self.iter.next()
879    }
880
881    fn size_hint(&self) -> (usize, Option<usize>) {
882        self.iter.size_hint()
883    }
884}
885
886impl DoubleEndedIterator for Drain<'_> {
887    fn next_back(&mut self) -> Option<Self::Item> {
888        self.iter.next_back()
889    }
890}
891
892impl ExactSizeIterator for Drain<'_> {
893    fn len(&self) -> usize {
894        self.iter.len()
895    }
896}
897
898impl FusedIterator for Drain<'_> {}
899
900#[macro_export]
901macro_rules! record {
902    // The macro only compiles if the number of columns equals the number of values,
903    // so it's safe to call `unwrap` below.
904    {$($col:expr => $val:expr),+ $(,)?} => {
905        $crate::Record::from_raw_cols_vals(
906            ::std::vec![$($col.into(),)+],
907            ::std::vec![$($val,)+],
908            $crate::Span::unknown(),
909            $crate::Span::unknown(),
910        ).unwrap()
911    };
912    {} => {
913        $crate::Record::new()
914    };
915}