1use 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#[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 unsafe { &*(record as *const Record as *const Self) }
32 }
33
34 #[inline]
35 const fn from_record_mut(record: &mut Record) -> &mut Self {
36 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 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 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
135pub 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 pub fn reborrow(&self) -> DynCasedRecord<&Record> {
174 DynCasedRecord {
175 record: &*self.record,
176 casing: self.casing,
177 }
178 }
179
180 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 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 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 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 fn remove_index(&mut self, index: usize) -> Value {
348 self.inner.remove(index).1
349 }
350
351 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 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 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 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 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 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 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 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 {$($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}