1use std::{iter::FusedIterator, ops::RangeBounds};
3
4use crate::{ShellError, Span, Value, casing::Casing};
5
6use nu_utils::IgnoreCaseExt;
7use serde::{Deserialize, Serialize, de::Visitor, ser::SerializeMap};
8
9#[derive(Debug, Clone, Default)]
10pub struct Record {
11 inner: Vec<(String, Value)>,
12}
13
14pub struct CasedRecord<R> {
18 record: R,
19 casing: Casing,
20}
21
22impl<R> CasedRecord<R> {
23 fn cmp(&self, lhs: &str, rhs: &str) -> bool {
24 match self.casing {
25 Casing::Sensitive => lhs == rhs,
26 Casing::Insensitive => lhs.eq_ignore_case(rhs),
27 }
28 }
29}
30
31impl<'a> CasedRecord<&'a Record> {
32 pub fn contains(&self, col: impl AsRef<str>) -> bool {
33 self.record.columns().any(|k| self.cmp(k, col.as_ref()))
34 }
35
36 pub fn index_of(&self, col: impl AsRef<str>) -> Option<usize> {
37 self.record
38 .columns()
39 .rposition(|k| self.cmp(k, col.as_ref()))
40 }
41
42 pub fn get(self, col: impl AsRef<str>) -> Option<&'a Value> {
43 let idx = self.index_of(col)?;
44 let (_, value) = self.record.get_index(idx)?;
45 Some(value)
46 }
47}
48
49impl<'a> CasedRecord<&'a mut Record> {
50 fn shared(&'a self) -> CasedRecord<&'a Record> {
51 CasedRecord {
52 record: &*self.record,
53 casing: self.casing,
54 }
55 }
56
57 pub fn get_mut(self, col: impl AsRef<str>) -> Option<&'a mut Value> {
58 let idx = self.shared().index_of(col)?;
59 let (_, value) = self.record.get_index_mut(idx)?;
60 Some(value)
61 }
62
63 pub fn remove(&mut self, col: impl AsRef<str>) -> Option<Value> {
64 let idx = self.shared().index_of(col)?;
65 let (_, val) = self.record.inner.remove(idx);
66 Some(val)
67 }
68}
69
70impl Record {
71 pub fn new() -> Self {
72 Self::default()
73 }
74
75 pub fn with_capacity(capacity: usize) -> Self {
76 Self {
77 inner: Vec::with_capacity(capacity),
78 }
79 }
80
81 pub fn cased(&self, casing: Casing) -> CasedRecord<&Record> {
82 CasedRecord {
83 record: self,
84 casing,
85 }
86 }
87
88 pub fn cased_mut(&mut self, casing: Casing) -> CasedRecord<&mut Record> {
89 CasedRecord {
90 record: self,
91 casing,
92 }
93 }
94
95 pub fn from_raw_cols_vals(
102 cols: Vec<String>,
103 vals: Vec<Value>,
104 input_span: Span,
105 creation_site_span: Span,
106 ) -> Result<Self, ShellError> {
107 if cols.len() == vals.len() {
108 let inner = cols.into_iter().zip(vals).collect();
109 Ok(Self { inner })
110 } else {
111 Err(ShellError::RecordColsValsMismatch {
112 bad_value: input_span,
113 creation_site: creation_site_span,
114 })
115 }
116 }
117
118 pub fn iter(&self) -> Iter {
119 self.into_iter()
120 }
121
122 pub fn iter_mut(&mut self) -> IterMut {
123 self.into_iter()
124 }
125
126 pub fn is_empty(&self) -> bool {
127 self.inner.is_empty()
128 }
129
130 pub fn len(&self) -> usize {
131 self.inner.len()
132 }
133
134 pub fn push(&mut self, col: impl Into<String>, val: Value) {
140 self.inner.push((col.into(), val));
141 }
142
143 pub fn insert<K>(&mut self, col: K, val: Value) -> Option<Value>
147 where
148 K: AsRef<str> + Into<String>,
149 {
150 if let Some(curr_val) = self.get_mut(&col) {
151 Some(std::mem::replace(curr_val, val))
152 } else {
153 self.push(col, val);
154 None
155 }
156 }
157
158 pub fn contains(&self, col: impl AsRef<str>) -> bool {
159 self.columns().any(|k| k == col.as_ref())
160 }
161
162 pub fn index_of(&self, col: impl AsRef<str>) -> Option<usize> {
163 self.columns().position(|k| k == col.as_ref())
164 }
165
166 pub fn get(&self, col: impl AsRef<str>) -> Option<&Value> {
167 self.inner
168 .iter()
169 .find_map(|(k, v)| if k == col.as_ref() { Some(v) } else { None })
170 }
171
172 pub fn get_mut(&mut self, col: impl AsRef<str>) -> Option<&mut Value> {
173 self.inner
174 .iter_mut()
175 .find_map(|(k, v)| if k == col.as_ref() { Some(v) } else { None })
176 }
177
178 pub fn get_index(&self, idx: usize) -> Option<(&String, &Value)> {
179 self.inner.get(idx).map(|(col, val): &(_, _)| (col, val))
180 }
181
182 pub fn get_index_mut(&mut self, idx: usize) -> Option<(&mut String, &mut Value)> {
183 self.inner
184 .get_mut(idx)
185 .map(|(col, val): &mut (_, _)| (col, val))
186 }
187
188 pub fn remove(&mut self, col: impl AsRef<str>) -> Option<Value> {
194 let idx = self.index_of(col)?;
195 let (_, val) = self.inner.remove(idx);
196 Some(val)
197 }
198
199 pub fn retain<F>(&mut self, mut keep: F)
217 where
218 F: FnMut(&str, &Value) -> bool,
219 {
220 self.retain_mut(|k, v| keep(k, v));
221 }
222
223 pub fn retain_mut<F>(&mut self, mut keep: F)
261 where
262 F: FnMut(&str, &mut Value) -> bool,
263 {
264 self.inner.retain_mut(|(col, val)| keep(col, val));
265 }
266
267 pub fn truncate(&mut self, len: usize) {
288 self.inner.truncate(len);
289 }
290
291 pub fn columns(&self) -> Columns {
292 Columns {
293 iter: self.inner.iter(),
294 }
295 }
296
297 pub fn into_columns(self) -> IntoColumns {
298 IntoColumns {
299 iter: self.inner.into_iter(),
300 }
301 }
302
303 pub fn values(&self) -> Values {
304 Values {
305 iter: self.inner.iter(),
306 }
307 }
308
309 pub fn into_values(self) -> IntoValues {
310 IntoValues {
311 iter: self.inner.into_iter(),
312 }
313 }
314
315 pub fn drain<R>(&mut self, range: R) -> Drain
337 where
338 R: RangeBounds<usize> + Clone,
339 {
340 Drain {
341 iter: self.inner.drain(range),
342 }
343 }
344
345 pub fn sort_cols(&mut self) {
368 self.inner.sort_by(|(k1, _), (k2, _)| k1.cmp(k2))
369 }
370}
371
372impl Serialize for Record {
373 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
374 where
375 S: serde::Serializer,
376 {
377 let mut map = serializer.serialize_map(Some(self.len()))?;
378 for (k, v) in self {
379 map.serialize_entry(k, v)?;
380 }
381 map.end()
382 }
383}
384
385impl<'de> Deserialize<'de> for Record {
386 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
410 where
411 D: serde::Deserializer<'de>,
412 {
413 deserializer.deserialize_map(RecordVisitor)
414 }
415}
416
417struct RecordVisitor;
418
419impl<'de> Visitor<'de> for RecordVisitor {
420 type Value = Record;
421
422 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
423 formatter.write_str("a nushell `Record` mapping string keys/columns to nushell `Value`")
424 }
425
426 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
427 where
428 A: serde::de::MapAccess<'de>,
429 {
430 let mut record = Record::with_capacity(map.size_hint().unwrap_or(0));
431
432 while let Some((key, value)) = map.next_entry::<String, Value>()? {
433 if record.insert(key, value).is_some() {
434 return Err(serde::de::Error::custom(
435 "invalid entry, duplicate keys are not allowed for `Record`",
436 ));
437 }
438 }
439
440 Ok(record)
441 }
442}
443
444impl FromIterator<(String, Value)> for Record {
445 fn from_iter<T: IntoIterator<Item = (String, Value)>>(iter: T) -> Self {
446 Self {
448 inner: iter.into_iter().collect(),
449 }
450 }
451}
452
453impl Extend<(String, Value)> for Record {
454 fn extend<T: IntoIterator<Item = (String, Value)>>(&mut self, iter: T) {
455 for (k, v) in iter {
456 self.push(k, v)
458 }
459 }
460}
461
462pub struct IntoIter {
463 iter: std::vec::IntoIter<(String, Value)>,
464}
465
466impl Iterator for IntoIter {
467 type Item = (String, Value);
468
469 fn next(&mut self) -> Option<Self::Item> {
470 self.iter.next()
471 }
472
473 fn size_hint(&self) -> (usize, Option<usize>) {
474 self.iter.size_hint()
475 }
476}
477
478impl DoubleEndedIterator for IntoIter {
479 fn next_back(&mut self) -> Option<Self::Item> {
480 self.iter.next_back()
481 }
482}
483
484impl ExactSizeIterator for IntoIter {
485 fn len(&self) -> usize {
486 self.iter.len()
487 }
488}
489
490impl FusedIterator for IntoIter {}
491
492impl IntoIterator for Record {
493 type Item = (String, Value);
494
495 type IntoIter = IntoIter;
496
497 fn into_iter(self) -> Self::IntoIter {
498 IntoIter {
499 iter: self.inner.into_iter(),
500 }
501 }
502}
503
504pub struct Iter<'a> {
505 iter: std::slice::Iter<'a, (String, Value)>,
506}
507
508impl<'a> Iterator for Iter<'a> {
509 type Item = (&'a String, &'a Value);
510
511 fn next(&mut self) -> Option<Self::Item> {
512 self.iter.next().map(|(col, val): &(_, _)| (col, val))
513 }
514
515 fn size_hint(&self) -> (usize, Option<usize>) {
516 self.iter.size_hint()
517 }
518}
519
520impl DoubleEndedIterator for Iter<'_> {
521 fn next_back(&mut self) -> Option<Self::Item> {
522 self.iter.next_back().map(|(col, val): &(_, _)| (col, val))
523 }
524}
525
526impl ExactSizeIterator for Iter<'_> {
527 fn len(&self) -> usize {
528 self.iter.len()
529 }
530}
531
532impl FusedIterator for Iter<'_> {}
533
534impl<'a> IntoIterator for &'a Record {
535 type Item = (&'a String, &'a Value);
536
537 type IntoIter = Iter<'a>;
538
539 fn into_iter(self) -> Self::IntoIter {
540 Iter {
541 iter: self.inner.iter(),
542 }
543 }
544}
545
546pub struct IterMut<'a> {
547 iter: std::slice::IterMut<'a, (String, Value)>,
548}
549
550impl<'a> Iterator for IterMut<'a> {
551 type Item = (&'a String, &'a mut Value);
552
553 fn next(&mut self) -> Option<Self::Item> {
554 self.iter.next().map(|(col, val)| (&*col, val))
555 }
556
557 fn size_hint(&self) -> (usize, Option<usize>) {
558 self.iter.size_hint()
559 }
560}
561
562impl DoubleEndedIterator for IterMut<'_> {
563 fn next_back(&mut self) -> Option<Self::Item> {
564 self.iter.next_back().map(|(col, val)| (&*col, val))
565 }
566}
567
568impl ExactSizeIterator for IterMut<'_> {
569 fn len(&self) -> usize {
570 self.iter.len()
571 }
572}
573
574impl FusedIterator for IterMut<'_> {}
575
576impl<'a> IntoIterator for &'a mut Record {
577 type Item = (&'a String, &'a mut Value);
578
579 type IntoIter = IterMut<'a>;
580
581 fn into_iter(self) -> Self::IntoIter {
582 IterMut {
583 iter: self.inner.iter_mut(),
584 }
585 }
586}
587
588pub struct Columns<'a> {
589 iter: std::slice::Iter<'a, (String, Value)>,
590}
591
592impl<'a> Iterator for Columns<'a> {
593 type Item = &'a String;
594
595 fn next(&mut self) -> Option<Self::Item> {
596 self.iter.next().map(|(col, _)| col)
597 }
598
599 fn size_hint(&self) -> (usize, Option<usize>) {
600 self.iter.size_hint()
601 }
602}
603
604impl DoubleEndedIterator for Columns<'_> {
605 fn next_back(&mut self) -> Option<Self::Item> {
606 self.iter.next_back().map(|(col, _)| col)
607 }
608}
609
610impl ExactSizeIterator for Columns<'_> {
611 fn len(&self) -> usize {
612 self.iter.len()
613 }
614}
615
616impl FusedIterator for Columns<'_> {}
617
618pub struct IntoColumns {
619 iter: std::vec::IntoIter<(String, Value)>,
620}
621
622impl Iterator for IntoColumns {
623 type Item = String;
624
625 fn next(&mut self) -> Option<Self::Item> {
626 self.iter.next().map(|(col, _)| col)
627 }
628
629 fn size_hint(&self) -> (usize, Option<usize>) {
630 self.iter.size_hint()
631 }
632}
633
634impl DoubleEndedIterator for IntoColumns {
635 fn next_back(&mut self) -> Option<Self::Item> {
636 self.iter.next_back().map(|(col, _)| col)
637 }
638}
639
640impl ExactSizeIterator for IntoColumns {
641 fn len(&self) -> usize {
642 self.iter.len()
643 }
644}
645
646impl FusedIterator for IntoColumns {}
647
648pub struct Values<'a> {
649 iter: std::slice::Iter<'a, (String, Value)>,
650}
651
652impl<'a> Iterator for Values<'a> {
653 type Item = &'a Value;
654
655 fn next(&mut self) -> Option<Self::Item> {
656 self.iter.next().map(|(_, val)| val)
657 }
658
659 fn size_hint(&self) -> (usize, Option<usize>) {
660 self.iter.size_hint()
661 }
662}
663
664impl DoubleEndedIterator for Values<'_> {
665 fn next_back(&mut self) -> Option<Self::Item> {
666 self.iter.next_back().map(|(_, val)| val)
667 }
668}
669
670impl ExactSizeIterator for Values<'_> {
671 fn len(&self) -> usize {
672 self.iter.len()
673 }
674}
675
676impl FusedIterator for Values<'_> {}
677
678pub struct IntoValues {
679 iter: std::vec::IntoIter<(String, Value)>,
680}
681
682impl Iterator for IntoValues {
683 type Item = Value;
684
685 fn next(&mut self) -> Option<Self::Item> {
686 self.iter.next().map(|(_, val)| val)
687 }
688
689 fn size_hint(&self) -> (usize, Option<usize>) {
690 self.iter.size_hint()
691 }
692}
693
694impl DoubleEndedIterator for IntoValues {
695 fn next_back(&mut self) -> Option<Self::Item> {
696 self.iter.next_back().map(|(_, val)| val)
697 }
698}
699
700impl ExactSizeIterator for IntoValues {
701 fn len(&self) -> usize {
702 self.iter.len()
703 }
704}
705
706impl FusedIterator for IntoValues {}
707
708pub struct Drain<'a> {
709 iter: std::vec::Drain<'a, (String, Value)>,
710}
711
712impl Iterator for Drain<'_> {
713 type Item = (String, Value);
714
715 fn next(&mut self) -> Option<Self::Item> {
716 self.iter.next()
717 }
718
719 fn size_hint(&self) -> (usize, Option<usize>) {
720 self.iter.size_hint()
721 }
722}
723
724impl DoubleEndedIterator for Drain<'_> {
725 fn next_back(&mut self) -> Option<Self::Item> {
726 self.iter.next_back()
727 }
728}
729
730impl ExactSizeIterator for Drain<'_> {
731 fn len(&self) -> usize {
732 self.iter.len()
733 }
734}
735
736impl FusedIterator for Drain<'_> {}
737
738#[macro_export]
739macro_rules! record {
740 {$($col:expr => $val:expr),+ $(,)?} => {
743 $crate::Record::from_raw_cols_vals(
744 ::std::vec![$($col.into(),)+],
745 ::std::vec![$($val,)+],
746 $crate::Span::unknown(),
747 $crate::Span::unknown(),
748 ).unwrap()
749 };
750 {} => {
751 $crate::Record::new()
752 };
753}