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 memory_size(&self) -> usize {
276 std::mem::size_of::<Self>()
277 + self
278 .inner
279 .iter()
280 .map(|(k, v)| k.capacity() + v.memory_size())
281 .sum::<usize>()
282 }
283
284 pub fn cased(&self, casing: Casing) -> DynCasedRecord<&Record> {
285 DynCasedRecord {
286 record: self,
287 casing,
288 }
289 }
290
291 pub fn cased_mut(&mut self, casing: Casing) -> DynCasedRecord<&mut Record> {
292 DynCasedRecord {
293 record: self,
294 casing,
295 }
296 }
297
298 pub fn from_raw_cols_vals(
305 cols: Vec<String>,
306 vals: Vec<Value>,
307 input_span: Span,
308 creation_site_span: Span,
309 ) -> Result<Self, ShellError> {
310 if cols.len() == vals.len() {
311 let inner = cols.into_iter().zip(vals).collect();
312 Ok(Self { inner })
313 } else {
314 Err(ShellError::RecordColsValsMismatch {
315 bad_value: input_span,
316 creation_site: creation_site_span,
317 })
318 }
319 }
320
321 pub fn iter(&self) -> Iter<'_> {
322 self.into_iter()
323 }
324
325 pub fn iter_mut(&mut self) -> IterMut<'_> {
326 self.into_iter()
327 }
328
329 pub fn is_empty(&self) -> bool {
330 self.inner.is_empty()
331 }
332
333 pub fn len(&self) -> usize {
334 self.inner.len()
335 }
336
337 pub fn push(&mut self, col: impl Into<String>, val: Value) {
345 self.inner.push((col.into(), val));
346 }
347
348 pub fn get_index(&self, idx: usize) -> Option<(&String, &Value)> {
349 self.inner.get(idx).map(|(col, val): &(_, _)| (col, val))
350 }
351
352 pub fn get_index_mut(&mut self, idx: usize) -> Option<(&mut String, &mut Value)> {
353 self.inner.get_mut(idx).map(|(col, val)| (col, val))
354 }
355
356 fn remove_index(&mut self, index: usize) -> Value {
358 self.inner.remove(index).1
359 }
360
361 pub fn retain<F>(&mut self, mut keep: F)
379 where
380 F: FnMut(&str, &Value) -> bool,
381 {
382 self.retain_mut(|k, v| keep(k, v));
383 }
384
385 pub fn retain_mut<F>(&mut self, mut keep: F)
423 where
424 F: FnMut(&str, &mut Value) -> bool,
425 {
426 self.inner.retain_mut(|(col, val)| keep(col, val));
427 }
428
429 pub fn truncate(&mut self, len: usize) {
450 self.inner.truncate(len);
451 }
452
453 pub fn columns(&self) -> Columns<'_> {
454 Columns {
455 iter: self.inner.iter(),
456 }
457 }
458
459 pub fn into_columns(self) -> IntoColumns {
460 IntoColumns {
461 iter: self.inner.into_iter(),
462 }
463 }
464
465 pub fn values(&self) -> Values<'_> {
466 Values {
467 iter: self.inner.iter(),
468 }
469 }
470
471 pub fn into_values(self) -> IntoValues {
472 IntoValues {
473 iter: self.inner.into_iter(),
474 }
475 }
476
477 pub fn drain<R>(&mut self, range: R) -> Drain<'_>
499 where
500 R: RangeBounds<usize> + Clone,
501 {
502 Drain {
503 iter: self.inner.drain(range),
504 }
505 }
506
507 pub fn sort_cols(&mut self) {
530 self.inner.sort_by(|(k1, _), (k2, _)| k1.cmp(k2))
531 }
532}
533
534impl Serialize for Record {
535 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
536 where
537 S: serde::Serializer,
538 {
539 let mut map = serializer.serialize_map(Some(self.len()))?;
540 for (k, v) in self {
541 map.serialize_entry(k, v)?;
542 }
543 map.end()
544 }
545}
546
547impl<'de> Deserialize<'de> for Record {
548 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
572 where
573 D: serde::Deserializer<'de>,
574 {
575 deserializer.deserialize_map(RecordVisitor)
576 }
577}
578
579struct RecordVisitor;
580
581impl<'de> Visitor<'de> for RecordVisitor {
582 type Value = Record;
583
584 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
585 formatter.write_str("a nushell `Record` mapping string keys/columns to nushell `Value`")
586 }
587
588 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
589 where
590 A: serde::de::MapAccess<'de>,
591 {
592 let mut record = Record::with_capacity(map.size_hint().unwrap_or(0));
593
594 while let Some((key, value)) = map.next_entry::<String, Value>()? {
595 if record.insert(key, value).is_some() {
596 return Err(serde::de::Error::custom(
597 "invalid entry, duplicate keys are not allowed for `Record`",
598 ));
599 }
600 }
601
602 Ok(record)
603 }
604}
605
606impl FromIterator<(String, Value)> for Record {
607 fn from_iter<T: IntoIterator<Item = (String, Value)>>(iter: T) -> Self {
608 Self {
610 inner: iter.into_iter().collect(),
611 }
612 }
613}
614
615impl Extend<(String, Value)> for Record {
616 fn extend<T: IntoIterator<Item = (String, Value)>>(&mut self, iter: T) {
617 for (k, v) in iter {
618 self.push(k, v)
620 }
621 }
622}
623
624pub struct IntoIter {
625 iter: std::vec::IntoIter<(String, Value)>,
626}
627
628impl Iterator for IntoIter {
629 type Item = (String, Value);
630
631 fn next(&mut self) -> Option<Self::Item> {
632 self.iter.next()
633 }
634
635 fn size_hint(&self) -> (usize, Option<usize>) {
636 self.iter.size_hint()
637 }
638}
639
640impl DoubleEndedIterator for IntoIter {
641 fn next_back(&mut self) -> Option<Self::Item> {
642 self.iter.next_back()
643 }
644}
645
646impl ExactSizeIterator for IntoIter {
647 fn len(&self) -> usize {
648 self.iter.len()
649 }
650}
651
652impl FusedIterator for IntoIter {}
653
654impl IntoIterator for Record {
655 type Item = (String, Value);
656
657 type IntoIter = IntoIter;
658
659 fn into_iter(self) -> Self::IntoIter {
660 IntoIter {
661 iter: self.inner.into_iter(),
662 }
663 }
664}
665
666pub struct Iter<'a> {
667 iter: std::slice::Iter<'a, (String, Value)>,
668}
669
670impl<'a> Iterator for Iter<'a> {
671 type Item = (&'a String, &'a Value);
672
673 fn next(&mut self) -> Option<Self::Item> {
674 self.iter.next().map(|(col, val): &(_, _)| (col, val))
675 }
676
677 fn size_hint(&self) -> (usize, Option<usize>) {
678 self.iter.size_hint()
679 }
680}
681
682impl DoubleEndedIterator for Iter<'_> {
683 fn next_back(&mut self) -> Option<Self::Item> {
684 self.iter.next_back().map(|(col, val): &(_, _)| (col, val))
685 }
686}
687
688impl ExactSizeIterator for Iter<'_> {
689 fn len(&self) -> usize {
690 self.iter.len()
691 }
692}
693
694impl FusedIterator for Iter<'_> {}
695
696impl<'a> IntoIterator for &'a Record {
697 type Item = (&'a String, &'a Value);
698
699 type IntoIter = Iter<'a>;
700
701 fn into_iter(self) -> Self::IntoIter {
702 Iter {
703 iter: self.inner.iter(),
704 }
705 }
706}
707
708pub struct IterMut<'a> {
709 iter: std::slice::IterMut<'a, (String, Value)>,
710}
711
712impl<'a> Iterator for IterMut<'a> {
713 type Item = (&'a String, &'a mut Value);
714
715 fn next(&mut self) -> Option<Self::Item> {
716 self.iter.next().map(|(col, val)| (&*col, val))
717 }
718
719 fn size_hint(&self) -> (usize, Option<usize>) {
720 self.iter.size_hint()
721 }
722}
723
724impl DoubleEndedIterator for IterMut<'_> {
725 fn next_back(&mut self) -> Option<Self::Item> {
726 self.iter.next_back().map(|(col, val)| (&*col, val))
727 }
728}
729
730impl ExactSizeIterator for IterMut<'_> {
731 fn len(&self) -> usize {
732 self.iter.len()
733 }
734}
735
736impl FusedIterator for IterMut<'_> {}
737
738impl<'a> IntoIterator for &'a mut Record {
739 type Item = (&'a String, &'a mut Value);
740
741 type IntoIter = IterMut<'a>;
742
743 fn into_iter(self) -> Self::IntoIter {
744 IterMut {
745 iter: self.inner.iter_mut(),
746 }
747 }
748}
749
750pub struct Columns<'a> {
751 iter: std::slice::Iter<'a, (String, Value)>,
752}
753
754impl<'a> Iterator for Columns<'a> {
755 type Item = &'a String;
756
757 fn next(&mut self) -> Option<Self::Item> {
758 self.iter.next().map(|(col, _)| col)
759 }
760
761 fn size_hint(&self) -> (usize, Option<usize>) {
762 self.iter.size_hint()
763 }
764}
765
766impl DoubleEndedIterator for Columns<'_> {
767 fn next_back(&mut self) -> Option<Self::Item> {
768 self.iter.next_back().map(|(col, _)| col)
769 }
770}
771
772impl ExactSizeIterator for Columns<'_> {
773 fn len(&self) -> usize {
774 self.iter.len()
775 }
776}
777
778impl FusedIterator for Columns<'_> {}
779
780pub struct IntoColumns {
781 iter: std::vec::IntoIter<(String, Value)>,
782}
783
784impl Iterator for IntoColumns {
785 type Item = String;
786
787 fn next(&mut self) -> Option<Self::Item> {
788 self.iter.next().map(|(col, _)| col)
789 }
790
791 fn size_hint(&self) -> (usize, Option<usize>) {
792 self.iter.size_hint()
793 }
794}
795
796impl DoubleEndedIterator for IntoColumns {
797 fn next_back(&mut self) -> Option<Self::Item> {
798 self.iter.next_back().map(|(col, _)| col)
799 }
800}
801
802impl ExactSizeIterator for IntoColumns {
803 fn len(&self) -> usize {
804 self.iter.len()
805 }
806}
807
808impl FusedIterator for IntoColumns {}
809
810pub struct Values<'a> {
811 iter: std::slice::Iter<'a, (String, Value)>,
812}
813
814impl<'a> Iterator for Values<'a> {
815 type Item = &'a Value;
816
817 fn next(&mut self) -> Option<Self::Item> {
818 self.iter.next().map(|(_, val)| val)
819 }
820
821 fn size_hint(&self) -> (usize, Option<usize>) {
822 self.iter.size_hint()
823 }
824}
825
826impl DoubleEndedIterator for Values<'_> {
827 fn next_back(&mut self) -> Option<Self::Item> {
828 self.iter.next_back().map(|(_, val)| val)
829 }
830}
831
832impl ExactSizeIterator for Values<'_> {
833 fn len(&self) -> usize {
834 self.iter.len()
835 }
836}
837
838impl FusedIterator for Values<'_> {}
839
840pub struct IntoValues {
841 iter: std::vec::IntoIter<(String, Value)>,
842}
843
844impl Iterator for IntoValues {
845 type Item = Value;
846
847 fn next(&mut self) -> Option<Self::Item> {
848 self.iter.next().map(|(_, val)| val)
849 }
850
851 fn size_hint(&self) -> (usize, Option<usize>) {
852 self.iter.size_hint()
853 }
854}
855
856impl DoubleEndedIterator for IntoValues {
857 fn next_back(&mut self) -> Option<Self::Item> {
858 self.iter.next_back().map(|(_, val)| val)
859 }
860}
861
862impl ExactSizeIterator for IntoValues {
863 fn len(&self) -> usize {
864 self.iter.len()
865 }
866}
867
868impl FusedIterator for IntoValues {}
869
870pub struct Drain<'a> {
871 iter: std::vec::Drain<'a, (String, Value)>,
872}
873
874impl Iterator for Drain<'_> {
875 type Item = (String, Value);
876
877 fn next(&mut self) -> Option<Self::Item> {
878 self.iter.next()
879 }
880
881 fn size_hint(&self) -> (usize, Option<usize>) {
882 self.iter.size_hint()
883 }
884}
885
886impl DoubleEndedIterator for Drain<'_> {
887 fn next_back(&mut self) -> Option<Self::Item> {
888 self.iter.next_back()
889 }
890}
891
892impl ExactSizeIterator for Drain<'_> {
893 fn len(&self) -> usize {
894 self.iter.len()
895 }
896}
897
898impl FusedIterator for Drain<'_> {}
899
900#[macro_export]
901macro_rules! record {
902 {$($col:expr => $val:expr),+ $(,)?} => {
905 $crate::Record::from_raw_cols_vals(
906 ::std::vec![$($col.into(),)+],
907 ::std::vec![$($val,)+],
908 $crate::Span::unknown(),
909 $crate::Span::unknown(),
910 ).unwrap()
911 };
912 {} => {
913 $crate::Record::new()
914 };
915}