nu_data/
dict.rs

1use derive_new::new;
2use nu_protocol::{Dictionary, MaybeOwned, Primitive, UntaggedValue, Value};
3use nu_source::{DbgDocBldr, DebugDocBuilder, PrettyDebug, Spanned, Tag};
4
5#[derive(Debug, new)]
6struct DebugEntry<'a> {
7    key: &'a str,
8    value: &'a Value,
9}
10
11impl<'a> PrettyDebug for DebugEntry<'a> {
12    fn pretty(&self) -> DebugDocBuilder {
13        (DbgDocBldr::key(self.key.to_string())
14            + DbgDocBldr::equals()
15            + self.value.pretty().into_value())
16        .group()
17    }
18}
19
20pub trait DictionaryExt {
21    fn get_data(&self, desc: &str) -> MaybeOwned<'_, Value>;
22
23    fn keys(&self) -> indexmap::map::Keys<String, Value>;
24    fn get_data_by_key(&self, name: Spanned<&str>) -> Option<Value>;
25    fn get_mut_data_by_key(&mut self, name: &str) -> Option<&mut Value>;
26    fn insert_data_at_key(&mut self, name: &str, value: Value);
27}
28
29impl DictionaryExt for Dictionary {
30    fn get_data(&self, desc: &str) -> MaybeOwned<'_, Value> {
31        match self.entries.get(desc) {
32            Some(v) => MaybeOwned::Borrowed(v),
33            None => MaybeOwned::Owned(
34                UntaggedValue::Primitive(Primitive::Nothing).into_untagged_value(),
35            ),
36        }
37    }
38
39    fn keys(&self) -> indexmap::map::Keys<String, Value> {
40        self.entries.keys()
41    }
42
43    fn get_data_by_key(&self, name: Spanned<&str>) -> Option<Value> {
44        let result = self
45            .entries
46            .iter()
47            .find(|&(desc_name, _)| desc_name == name.item)?
48            .1;
49
50        Some(
51            result
52                .value
53                .clone()
54                .into_value(Tag::new(result.anchor(), name.span)),
55        )
56    }
57
58    fn get_mut_data_by_key(&mut self, name: &str) -> Option<&mut Value> {
59        self.entries
60            .iter_mut()
61            .find(|&(desc_name, _)| desc_name == name)
62            .map_or_else(|| None, |x| Some(x.1))
63    }
64
65    fn insert_data_at_key(&mut self, name: &str, value: Value) {
66        self.entries.insert(name.to_string(), value);
67    }
68}
69
70#[derive(Debug)]
71pub struct TaggedListBuilder {
72    tag: Tag,
73    pub list: Vec<Value>,
74}
75
76impl TaggedListBuilder {
77    pub fn new(tag: impl Into<Tag>) -> TaggedListBuilder {
78        TaggedListBuilder {
79            tag: tag.into(),
80            list: vec![],
81        }
82    }
83
84    pub fn push_value(&mut self, value: impl Into<Value>) {
85        self.list.push(value.into());
86    }
87
88    pub fn push_untagged(&mut self, value: impl Into<UntaggedValue>) {
89        self.list.push(value.into().into_value(self.tag.clone()));
90    }
91
92    pub fn into_value(self) -> Value {
93        UntaggedValue::Table(self.list).into_value(self.tag)
94    }
95
96    pub fn into_untagged_value(self) -> UntaggedValue {
97        UntaggedValue::Table(self.list).into_value(self.tag).value
98    }
99}
100
101impl From<TaggedListBuilder> for Value {
102    fn from(input: TaggedListBuilder) -> Value {
103        input.into_value()
104    }
105}