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}