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    pub fn cased(&self, casing: Casing) -> DynCasedRecord<&Record> {
275        DynCasedRecord {
276            record: self,
277            casing,
278        }
279    }
280
281    pub fn cased_mut(&mut self, casing: Casing) -> DynCasedRecord<&mut Record> {
282        DynCasedRecord {
283            record: self,
284            casing,
285        }
286    }
287
288    /// Create a [`Record`] from a `Vec` of columns and a `Vec` of [`Value`]s
289    ///
290    /// Returns an error if `cols` and `vals` have different lengths.
291    ///
292    /// For perf reasons, this will not validate the rest of the record assumptions:
293    /// - unique keys
294    pub fn from_raw_cols_vals(
295        cols: Vec<String>,
296        vals: Vec<Value>,
297        input_span: Span,
298        creation_site_span: Span,
299    ) -> Result<Self, ShellError> {
300        if cols.len() == vals.len() {
301            let inner = cols.into_iter().zip(vals).collect();
302            Ok(Self { inner })
303        } else {
304            Err(ShellError::RecordColsValsMismatch {
305                bad_value: input_span,
306                creation_site: creation_site_span,
307            })
308        }
309    }
310
311    pub fn iter(&self) -> Iter<'_> {
312        self.into_iter()
313    }
314
315    pub fn iter_mut(&mut self) -> IterMut<'_> {
316        self.into_iter()
317    }
318
319    pub fn is_empty(&self) -> bool {
320        self.inner.is_empty()
321    }
322
323    pub fn len(&self) -> usize {
324        self.inner.len()
325    }
326
327    /// Naive push to the end of the datastructure.
328    ///
329    /// <div class="warning">
330    /// May duplicate data!
331    ///
332    /// Consider using [`CasedRecord::insert`] or [`DynCasedRecord::insert`] instead.
333    /// </div>
334    pub fn push(&mut self, col: impl Into<String>, val: Value) {
335        self.inner.push((col.into(), val));
336    }
337
338    pub fn get_index(&self, idx: usize) -> Option<(&String, &Value)> {
339        self.inner.get(idx).map(|(col, val): &(_, _)| (col, val))
340    }
341
342    pub fn get_index_mut(&mut self, idx: usize) -> Option<(&mut String, &mut Value)> {
343        self.inner.get_mut(idx).map(|(col, val)| (col, val))
344    }
345
346    /// Remove single value by index
347    fn remove_index(&mut self, index: usize) -> Value {
348        self.inner.remove(index).1
349    }
350
351    /// Remove elements in-place that do not satisfy `keep`
352    ///
353    /// ```rust
354    /// use nu_protocol::{record, Value};
355    ///
356    /// let mut rec = record!(
357    ///     "a" => Value::test_nothing(),
358    ///     "b" => Value::test_int(42),
359    ///     "c" => Value::test_nothing(),
360    ///     "d" => Value::test_int(42),
361    /// );
362    /// rec.retain(|_k, val| !val.is_nothing());
363    /// let mut iter_rec = rec.columns();
364    /// assert_eq!(iter_rec.next().map(String::as_str), Some("b"));
365    /// assert_eq!(iter_rec.next().map(String::as_str), Some("d"));
366    /// assert_eq!(iter_rec.next(), None);
367    /// ```
368    pub fn retain<F>(&mut self, mut keep: F)
369    where
370        F: FnMut(&str, &Value) -> bool,
371    {
372        self.retain_mut(|k, v| keep(k, v));
373    }
374
375    /// Remove elements in-place that do not satisfy `keep` while allowing mutation of the value.
376    ///
377    /// This can for example be used to recursively prune nested records.
378    ///
379    /// ```rust
380    /// use nu_protocol::{record, Record, Value};
381    ///
382    /// fn remove_foo_recursively(val: &mut Value) {
383    ///     if let Value::Record {val, ..} = val {
384    ///         val.to_mut().retain_mut(keep_non_foo);
385    ///     }
386    /// }
387    ///
388    /// fn keep_non_foo(k: &str, v: &mut Value) -> bool {
389    ///     if k == "foo" {
390    ///         return false;
391    ///     }
392    ///     remove_foo_recursively(v);
393    ///     true
394    /// }
395    ///
396    /// let mut test = Value::test_record(record!(
397    ///     "foo" => Value::test_nothing(),
398    ///     "bar" => Value::test_record(record!(
399    ///         "foo" => Value::test_nothing(),
400    ///         "baz" => Value::test_nothing(),
401    ///         ))
402    ///     ));
403    ///
404    /// remove_foo_recursively(&mut test);
405    /// let expected = Value::test_record(record!(
406    ///     "bar" => Value::test_record(record!(
407    ///         "baz" => Value::test_nothing(),
408    ///         ))
409    ///     ));
410    /// assert_eq!(test, expected);
411    /// ```
412    pub fn retain_mut<F>(&mut self, mut keep: F)
413    where
414        F: FnMut(&str, &mut Value) -> bool,
415    {
416        self.inner.retain_mut(|(col, val)| keep(col, val));
417    }
418
419    /// Truncate record to the first `len` elements.
420    ///
421    /// `len > self.len()` will be ignored
422    ///
423    /// ```rust
424    /// use nu_protocol::{record, Value};
425    ///
426    /// let mut rec = record!(
427    ///     "a" => Value::test_nothing(),
428    ///     "b" => Value::test_int(42),
429    ///     "c" => Value::test_nothing(),
430    ///     "d" => Value::test_int(42),
431    /// );
432    /// rec.truncate(42); // this is fine
433    /// assert_eq!(rec.columns().map(String::as_str).collect::<String>(), "abcd");
434    /// rec.truncate(2); // truncate
435    /// assert_eq!(rec.columns().map(String::as_str).collect::<String>(), "ab");
436    /// rec.truncate(0); // clear the record
437    /// assert_eq!(rec.len(), 0);
438    /// ```
439    pub fn truncate(&mut self, len: usize) {
440        self.inner.truncate(len);
441    }
442
443    pub fn columns(&self) -> Columns<'_> {
444        Columns {
445            iter: self.inner.iter(),
446        }
447    }
448
449    pub fn into_columns(self) -> IntoColumns {
450        IntoColumns {
451            iter: self.inner.into_iter(),
452        }
453    }
454
455    pub fn values(&self) -> Values<'_> {
456        Values {
457            iter: self.inner.iter(),
458        }
459    }
460
461    pub fn into_values(self) -> IntoValues {
462        IntoValues {
463            iter: self.inner.into_iter(),
464        }
465    }
466
467    /// Obtain an iterator to remove elements in `range`
468    ///
469    /// Elements not consumed from the iterator will be dropped
470    ///
471    /// ```rust
472    /// use nu_protocol::{record, Value};
473    ///
474    /// let mut rec = record!(
475    ///     "a" => Value::test_nothing(),
476    ///     "b" => Value::test_int(42),
477    ///     "c" => Value::test_string("foo"),
478    /// );
479    /// {
480    ///     let mut drainer = rec.drain(1..);
481    ///     assert_eq!(drainer.next(), Some(("b".into(), Value::test_int(42))));
482    ///     // Dropping the `Drain`
483    /// }
484    /// let mut rec_iter = rec.into_iter();
485    /// assert_eq!(rec_iter.next(), Some(("a".into(), Value::test_nothing())));
486    /// assert_eq!(rec_iter.next(), None);
487    /// ```
488    pub fn drain<R>(&mut self, range: R) -> Drain<'_>
489    where
490        R: RangeBounds<usize> + Clone,
491    {
492        Drain {
493            iter: self.inner.drain(range),
494        }
495    }
496
497    /// Sort the record by its columns.
498    ///
499    /// ```rust
500    /// use nu_protocol::{record, Value};
501    ///
502    /// let mut rec = record!(
503    ///     "c" => Value::test_string("foo"),
504    ///     "b" => Value::test_int(42),
505    ///     "a" => Value::test_nothing(),
506    /// );
507    ///
508    /// rec.sort_cols();
509    ///
510    /// assert_eq!(
511    ///     Value::test_record(rec),
512    ///     Value::test_record(record!(
513    ///         "a" => Value::test_nothing(),
514    ///         "b" => Value::test_int(42),
515    ///         "c" => Value::test_string("foo"),
516    ///     ))
517    /// );
518    /// ```
519    pub fn sort_cols(&mut self) {
520        self.inner.sort_by(|(k1, _), (k2, _)| k1.cmp(k2))
521    }
522}
523
524impl Serialize for Record {
525    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
526    where
527        S: serde::Serializer,
528    {
529        let mut map = serializer.serialize_map(Some(self.len()))?;
530        for (k, v) in self {
531            map.serialize_entry(k, v)?;
532        }
533        map.end()
534    }
535}
536
537impl<'de> Deserialize<'de> for Record {
538    /// Special deserialization implementation that turns a map-pattern into a [`Record`]
539    ///
540    /// Denies duplicate keys
541    ///
542    /// ```rust
543    /// use serde_json::{from_str, Result};
544    /// use nu_protocol::{Record, Value, record};
545    ///
546    /// // A `Record` in json is a Record with a packed `Value`
547    /// // The `Value` record has a single key indicating its type and the inner record describing
548    /// // its representation of value and the associated `Span`
549    /// let ok = r#"{"a": {"Int": {"val": 42, "span": {"start": 0, "end": 0}}},
550    ///              "b": {"Int": {"val": 37, "span": {"start": 0, "end": 0}}}}"#;
551    /// let ok_rec: Record = from_str(ok).unwrap();
552    /// assert_eq!(Value::test_record(ok_rec),
553    ///            Value::test_record(record!{"a" => Value::test_int(42),
554    ///                                       "b" => Value::test_int(37)}));
555    /// // A repeated key will lead to a deserialization error
556    /// let bad = r#"{"a": {"Int": {"val": 42, "span": {"start": 0, "end": 0}}},
557    ///               "a": {"Int": {"val": 37, "span": {"start": 0, "end": 0}}}}"#;
558    /// let bad_rec: Result<Record> = from_str(bad);
559    /// assert!(bad_rec.is_err());
560    /// ```
561    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
562    where
563        D: serde::Deserializer<'de>,
564    {
565        deserializer.deserialize_map(RecordVisitor)
566    }
567}
568
569struct RecordVisitor;
570
571impl<'de> Visitor<'de> for RecordVisitor {
572    type Value = Record;
573
574    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
575        formatter.write_str("a nushell `Record` mapping string keys/columns to nushell `Value`")
576    }
577
578    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
579    where
580        A: serde::de::MapAccess<'de>,
581    {
582        let mut record = Record::with_capacity(map.size_hint().unwrap_or(0));
583
584        while let Some((key, value)) = map.next_entry::<String, Value>()? {
585            if record.insert(key, value).is_some() {
586                return Err(serde::de::Error::custom(
587                    "invalid entry, duplicate keys are not allowed for `Record`",
588                ));
589            }
590        }
591
592        Ok(record)
593    }
594}
595
596impl FromIterator<(String, Value)> for Record {
597    fn from_iter<T: IntoIterator<Item = (String, Value)>>(iter: T) -> Self {
598        // TODO: should this check for duplicate keys/columns?
599        Self {
600            inner: iter.into_iter().collect(),
601        }
602    }
603}
604
605impl Extend<(String, Value)> for Record {
606    fn extend<T: IntoIterator<Item = (String, Value)>>(&mut self, iter: T) {
607        for (k, v) in iter {
608            // TODO: should this .insert with a check?
609            self.push(k, v)
610        }
611    }
612}
613
614pub struct IntoIter {
615    iter: std::vec::IntoIter<(String, Value)>,
616}
617
618impl Iterator for IntoIter {
619    type Item = (String, Value);
620
621    fn next(&mut self) -> Option<Self::Item> {
622        self.iter.next()
623    }
624
625    fn size_hint(&self) -> (usize, Option<usize>) {
626        self.iter.size_hint()
627    }
628}
629
630impl DoubleEndedIterator for IntoIter {
631    fn next_back(&mut self) -> Option<Self::Item> {
632        self.iter.next_back()
633    }
634}
635
636impl ExactSizeIterator for IntoIter {
637    fn len(&self) -> usize {
638        self.iter.len()
639    }
640}
641
642impl FusedIterator for IntoIter {}
643
644impl IntoIterator for Record {
645    type Item = (String, Value);
646
647    type IntoIter = IntoIter;
648
649    fn into_iter(self) -> Self::IntoIter {
650        IntoIter {
651            iter: self.inner.into_iter(),
652        }
653    }
654}
655
656pub struct Iter<'a> {
657    iter: std::slice::Iter<'a, (String, Value)>,
658}
659
660impl<'a> Iterator for Iter<'a> {
661    type Item = (&'a String, &'a Value);
662
663    fn next(&mut self) -> Option<Self::Item> {
664        self.iter.next().map(|(col, val): &(_, _)| (col, val))
665    }
666
667    fn size_hint(&self) -> (usize, Option<usize>) {
668        self.iter.size_hint()
669    }
670}
671
672impl DoubleEndedIterator for Iter<'_> {
673    fn next_back(&mut self) -> Option<Self::Item> {
674        self.iter.next_back().map(|(col, val): &(_, _)| (col, val))
675    }
676}
677
678impl ExactSizeIterator for Iter<'_> {
679    fn len(&self) -> usize {
680        self.iter.len()
681    }
682}
683
684impl FusedIterator for Iter<'_> {}
685
686impl<'a> IntoIterator for &'a Record {
687    type Item = (&'a String, &'a Value);
688
689    type IntoIter = Iter<'a>;
690
691    fn into_iter(self) -> Self::IntoIter {
692        Iter {
693            iter: self.inner.iter(),
694        }
695    }
696}
697
698pub struct IterMut<'a> {
699    iter: std::slice::IterMut<'a, (String, Value)>,
700}
701
702impl<'a> Iterator for IterMut<'a> {
703    type Item = (&'a String, &'a mut Value);
704
705    fn next(&mut self) -> Option<Self::Item> {
706        self.iter.next().map(|(col, val)| (&*col, val))
707    }
708
709    fn size_hint(&self) -> (usize, Option<usize>) {
710        self.iter.size_hint()
711    }
712}
713
714impl DoubleEndedIterator for IterMut<'_> {
715    fn next_back(&mut self) -> Option<Self::Item> {
716        self.iter.next_back().map(|(col, val)| (&*col, val))
717    }
718}
719
720impl ExactSizeIterator for IterMut<'_> {
721    fn len(&self) -> usize {
722        self.iter.len()
723    }
724}
725
726impl FusedIterator for IterMut<'_> {}
727
728impl<'a> IntoIterator for &'a mut Record {
729    type Item = (&'a String, &'a mut Value);
730
731    type IntoIter = IterMut<'a>;
732
733    fn into_iter(self) -> Self::IntoIter {
734        IterMut {
735            iter: self.inner.iter_mut(),
736        }
737    }
738}
739
740pub struct Columns<'a> {
741    iter: std::slice::Iter<'a, (String, Value)>,
742}
743
744impl<'a> Iterator for Columns<'a> {
745    type Item = &'a String;
746
747    fn next(&mut self) -> Option<Self::Item> {
748        self.iter.next().map(|(col, _)| col)
749    }
750
751    fn size_hint(&self) -> (usize, Option<usize>) {
752        self.iter.size_hint()
753    }
754}
755
756impl DoubleEndedIterator for Columns<'_> {
757    fn next_back(&mut self) -> Option<Self::Item> {
758        self.iter.next_back().map(|(col, _)| col)
759    }
760}
761
762impl ExactSizeIterator for Columns<'_> {
763    fn len(&self) -> usize {
764        self.iter.len()
765    }
766}
767
768impl FusedIterator for Columns<'_> {}
769
770pub struct IntoColumns {
771    iter: std::vec::IntoIter<(String, Value)>,
772}
773
774impl Iterator for IntoColumns {
775    type Item = String;
776
777    fn next(&mut self) -> Option<Self::Item> {
778        self.iter.next().map(|(col, _)| col)
779    }
780
781    fn size_hint(&self) -> (usize, Option<usize>) {
782        self.iter.size_hint()
783    }
784}
785
786impl DoubleEndedIterator for IntoColumns {
787    fn next_back(&mut self) -> Option<Self::Item> {
788        self.iter.next_back().map(|(col, _)| col)
789    }
790}
791
792impl ExactSizeIterator for IntoColumns {
793    fn len(&self) -> usize {
794        self.iter.len()
795    }
796}
797
798impl FusedIterator for IntoColumns {}
799
800pub struct Values<'a> {
801    iter: std::slice::Iter<'a, (String, Value)>,
802}
803
804impl<'a> Iterator for Values<'a> {
805    type Item = &'a Value;
806
807    fn next(&mut self) -> Option<Self::Item> {
808        self.iter.next().map(|(_, val)| val)
809    }
810
811    fn size_hint(&self) -> (usize, Option<usize>) {
812        self.iter.size_hint()
813    }
814}
815
816impl DoubleEndedIterator for Values<'_> {
817    fn next_back(&mut self) -> Option<Self::Item> {
818        self.iter.next_back().map(|(_, val)| val)
819    }
820}
821
822impl ExactSizeIterator for Values<'_> {
823    fn len(&self) -> usize {
824        self.iter.len()
825    }
826}
827
828impl FusedIterator for Values<'_> {}
829
830pub struct IntoValues {
831    iter: std::vec::IntoIter<(String, Value)>,
832}
833
834impl Iterator for IntoValues {
835    type Item = Value;
836
837    fn next(&mut self) -> Option<Self::Item> {
838        self.iter.next().map(|(_, val)| val)
839    }
840
841    fn size_hint(&self) -> (usize, Option<usize>) {
842        self.iter.size_hint()
843    }
844}
845
846impl DoubleEndedIterator for IntoValues {
847    fn next_back(&mut self) -> Option<Self::Item> {
848        self.iter.next_back().map(|(_, val)| val)
849    }
850}
851
852impl ExactSizeIterator for IntoValues {
853    fn len(&self) -> usize {
854        self.iter.len()
855    }
856}
857
858impl FusedIterator for IntoValues {}
859
860pub struct Drain<'a> {
861    iter: std::vec::Drain<'a, (String, Value)>,
862}
863
864impl Iterator for Drain<'_> {
865    type Item = (String, Value);
866
867    fn next(&mut self) -> Option<Self::Item> {
868        self.iter.next()
869    }
870
871    fn size_hint(&self) -> (usize, Option<usize>) {
872        self.iter.size_hint()
873    }
874}
875
876impl DoubleEndedIterator for Drain<'_> {
877    fn next_back(&mut self) -> Option<Self::Item> {
878        self.iter.next_back()
879    }
880}
881
882impl ExactSizeIterator for Drain<'_> {
883    fn len(&self) -> usize {
884        self.iter.len()
885    }
886}
887
888impl FusedIterator for Drain<'_> {}
889
890#[macro_export]
891macro_rules! record {
892    // The macro only compiles if the number of columns equals the number of values,
893    // so it's safe to call `unwrap` below.
894    {$($col:expr => $val:expr),+ $(,)?} => {
895        $crate::Record::from_raw_cols_vals(
896            ::std::vec![$($col.into(),)+],
897            ::std::vec![$($val,)+],
898            $crate::Span::unknown(),
899            $crate::Span::unknown(),
900        ).unwrap()
901    };
902    {} => {
903        $crate::Record::new()
904    };
905}