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