1use 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#[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 unsafe { &*(record as *const Record as *const Self) }
41 }
42
43 #[inline]
44 const fn from_record_mut(record: &mut Record) -> &mut Self {
45 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 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 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
155pub 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 pub fn reborrow(&self) -> DynCasedRecord<&Record> {
194 DynCasedRecord {
195 record: &*self.record,
196 casing: self.casing,
197 }
198 }
199
200 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 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 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 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 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 fn remove_index(&mut self, index: usize) -> Value {
378 self.inner.remove(index).1
379 }
380
381 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 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 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 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 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 Some(TypeRelation::Equal)
592 } else {
593 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 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 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 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 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<'_> {}