nushell/src/object/dict.rs

173 lines
4.5 KiB
Rust
Raw Normal View History

2019-05-16 00:58:44 +02:00
use crate::prelude::*;
2019-05-10 18:59:12 +02:00
use crate::object::{Primitive, Value};
use derive_new::new;
use indexmap::IndexMap;
2019-07-03 19:37:09 +02:00
use serde::{Deserialize, Serialize};
2019-05-17 17:55:50 +02:00
use std::cmp::{Ordering, PartialOrd};
2019-06-22 05:43:37 +02:00
use std::fmt;
2019-05-10 18:59:12 +02:00
2019-07-03 19:37:09 +02:00
#[derive(Debug, Default, Eq, PartialEq, Serialize, Deserialize, Clone, new)]
2019-05-10 18:59:12 +02:00
pub struct Dictionary {
2019-07-08 18:44:53 +02:00
pub entries: IndexMap<String, Spanned<Value>>,
2019-05-10 18:59:12 +02:00
}
2019-05-17 17:55:50 +02:00
impl PartialOrd for Dictionary {
2019-06-24 02:55:31 +02:00
fn partial_cmp(&self, other: &Dictionary) -> Option<Ordering> {
2019-07-03 19:37:09 +02:00
let this: Vec<&String> = self.entries.keys().collect();
let that: Vec<&String> = other.entries.keys().collect();
2019-06-24 02:55:31 +02:00
if this != that {
return this.partial_cmp(&that);
}
2019-07-09 06:31:26 +02:00
let this: Vec<&Value> = self.entries.values().map(|v| v.item()).collect();
let that: Vec<&Value> = self.entries.values().map(|v| v.item()).collect();
2019-06-24 02:55:31 +02:00
this.partial_cmp(&that)
2019-05-17 17:55:50 +02:00
}
}
2019-07-08 18:44:53 +02:00
impl From<IndexMap<String, Spanned<Value>>> for Dictionary {
fn from(input: IndexMap<String, Spanned<Value>>) -> Dictionary {
let mut out = IndexMap::default();
for (key, value) in input {
2019-07-03 19:37:09 +02:00
out.insert(key, value);
}
Dictionary::new(out)
}
}
2019-05-17 17:55:50 +02:00
impl Ord for Dictionary {
2019-06-24 02:55:31 +02:00
fn cmp(&self, other: &Dictionary) -> Ordering {
2019-07-03 19:37:09 +02:00
let this: Vec<&String> = self.entries.keys().collect();
let that: Vec<&String> = other.entries.keys().collect();
2019-06-24 02:55:31 +02:00
if this != that {
return this.cmp(&that);
}
2019-07-09 06:31:26 +02:00
let this: Vec<&Value> = self.entries.values().map(|v| v.item()).collect();
let that: Vec<&Value> = self.entries.values().map(|v| v.item()).collect();
2019-06-24 02:55:31 +02:00
this.cmp(&that)
2019-05-17 17:55:50 +02:00
}
}
impl PartialOrd<Value> for Dictionary {
fn partial_cmp(&self, _other: &Value) -> Option<Ordering> {
Some(Ordering::Less)
}
}
impl PartialEq<Value> for Dictionary {
fn eq(&self, other: &Value) -> bool {
match other {
Value::Object(d) => self == d,
_ => false,
}
}
}
2019-05-10 18:59:12 +02:00
impl Dictionary {
2019-07-04 07:11:56 +02:00
pub fn get_data(&'a self, desc: &String) -> MaybeOwned<'a, Value> {
match self.entries.get(desc) {
Some(v) => MaybeOwned::Borrowed(v),
2019-05-10 18:59:12 +02:00
None => MaybeOwned::Owned(Value::Primitive(Primitive::Nothing)),
}
}
2019-05-17 17:55:50 +02:00
2019-07-08 18:44:53 +02:00
crate fn get_data_by_key(&self, name: &str) -> Option<&Spanned<Value>> {
match self
.entries
.iter()
2019-07-03 19:37:09 +02:00
.find(|(desc_name, _)| *desc_name == name)
{
2019-05-28 08:45:18 +02:00
Some((_, v)) => Some(v),
None => None,
2019-05-17 17:55:50 +02:00
}
}
2019-06-22 05:43:37 +02:00
crate fn debug(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut debug = f.debug_struct("Dictionary");
for (desc, value) in self.entries.iter() {
2019-07-03 19:37:09 +02:00
debug.field(desc, &value.debug());
2019-06-22 05:43:37 +02:00
}
debug.finish()
}
2019-05-10 18:59:12 +02:00
}
2019-07-08 18:44:53 +02:00
2019-07-09 06:31:26 +02:00
pub struct SpannedListBuilder {
span: Span,
list: Vec<Spanned<Value>>,
}
impl SpannedListBuilder {
pub fn new(span: impl Into<Span>) -> SpannedListBuilder {
SpannedListBuilder {
span: span.into(),
list: vec![],
}
}
pub fn push(&mut self, value: impl Into<Value>) {
self.list.push(value.into().spanned(self.span));
}
pub fn insert_spanned(&mut self, value: impl Into<Spanned<Value>>) {
self.list.push(value.into());
}
pub fn into_spanned_value(self) -> Spanned<Value> {
Value::List(self.list).spanned(self.span)
}
}
impl From<SpannedListBuilder> for Spanned<Value> {
fn from(input: SpannedListBuilder) -> Spanned<Value> {
input.into_spanned_value()
}
}
2019-07-08 18:44:53 +02:00
#[derive(Debug)]
pub struct SpannedDictBuilder {
span: Span,
2019-07-13 04:07:06 +02:00
dict: IndexMap<String, Spanned<Value>>,
2019-07-08 18:44:53 +02:00
}
impl SpannedDictBuilder {
pub fn new(span: impl Into<Span>) -> SpannedDictBuilder {
SpannedDictBuilder {
span: span.into(),
dict: IndexMap::default(),
}
}
2019-07-13 04:07:06 +02:00
pub fn insert(&mut self, key: impl Into<String>, value: impl Into<Value>) {
2019-07-08 18:44:53 +02:00
self.dict
.insert(key.into(), value.into().spanned(self.span));
}
2019-07-13 04:07:06 +02:00
pub fn insert_spanned(&mut self, key: impl Into<String>, value: impl Into<Spanned<Value>>) {
2019-07-08 18:44:53 +02:00
self.dict.insert(key.into(), value.into());
}
pub fn into_spanned_value(self) -> Spanned<Value> {
2019-07-09 06:31:26 +02:00
self.into_spanned_dict().map(Value::Object)
}
pub fn into_spanned_dict(self) -> Spanned<Dictionary> {
Dictionary { entries: self.dict }.spanned(self.span)
2019-07-08 18:44:53 +02:00
}
}
impl From<SpannedDictBuilder> for Spanned<Value> {
fn from(input: SpannedDictBuilder) -> Spanned<Value> {
input.into_spanned_value()
}
}