summaryrefslogtreecommitdiff
path: root/src/eval/dict.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval/dict.rs')
-rw-r--r--src/eval/dict.rs43
1 files changed, 38 insertions, 5 deletions
diff --git a/src/eval/dict.rs b/src/eval/dict.rs
index 9127b2eb..b630fc63 100644
--- a/src/eval/dict.rs
+++ b/src/eval/dict.rs
@@ -3,9 +3,11 @@ use std::fmt::{self, Debug, Formatter, Write};
use std::ops::{Add, AddAssign};
use std::sync::Arc;
-use super::Value;
-use crate::diag::StrResult;
+use super::{Args, Array, Func, Value};
+use crate::diag::{StrResult, TypResult};
+use crate::syntax::Spanned;
use crate::util::{ArcExt, EcoString};
+use crate::Context;
/// Create a new [`Dict`] from key-value pairs.
#[allow(unused_macros)]
@@ -56,14 +58,22 @@ impl Dict {
Arc::make_mut(&mut self.0).entry(key).or_default()
}
+ /// Whether the dictionary contains a specific key.
+ pub fn contains(&self, key: &str) -> bool {
+ self.0.contains_key(key)
+ }
+
/// Insert a mapping from the given `key` to the given `value`.
pub fn insert(&mut self, key: EcoString, value: Value) {
Arc::make_mut(&mut self.0).insert(key, value);
}
- /// Whether the dictionary contains a specific key.
- pub fn contains_key(&self, key: &str) -> bool {
- self.0.contains_key(key)
+ /// Remove a mapping by `key`.
+ pub fn remove(&mut self, key: EcoString) -> StrResult<()> {
+ match Arc::make_mut(&mut self.0).remove(&key) {
+ Some(_) => Ok(()),
+ None => Err(missing_key(&key)),
+ }
}
/// Clear the dictionary.
@@ -75,6 +85,29 @@ impl Dict {
}
}
+ /// Return the keys of the dictionary as an array.
+ pub fn keys(&self) -> Array {
+ self.iter().map(|(key, _)| Value::Str(key.clone())).collect()
+ }
+
+ /// Return the values of the dictionary as an array.
+ pub fn values(&self) -> Array {
+ self.iter().map(|(_, value)| value.clone()).collect()
+ }
+
+ /// Transform each pair in the array with a function.
+ pub fn map(&self, ctx: &mut Context, f: Spanned<Func>) -> TypResult<Array> {
+ Ok(self
+ .iter()
+ .map(|(key, value)| {
+ f.v.call(
+ ctx,
+ Args::from_values(f.span, [Value::Str(key.clone()), value.clone()]),
+ )
+ })
+ .collect::<TypResult<_>>()?)
+ }
+
/// Iterate over pairs of references to the contained keys and values.
pub fn iter(&self) -> std::collections::btree_map::Iter<EcoString, Value> {
self.0.iter()