Skip to main content

nu_protocol/value/
record.rs

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