summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorfrozolotl <44589151+frozolotl@users.noreply.github.com>2024-04-01 19:21:19 +0200
committerGitHub <noreply@github.com>2024-04-01 17:21:19 +0000
commit82717b28694d56a25f1bcb381258073255ef74cd (patch)
treedcbf849992c62d01e1353820d33ea1479c322bdb /crates
parent27259b714f4fe0f3c7cf877333f303e562680c76 (diff)
Implement `to-dict` method on arrays (#3575)
Diffstat (limited to 'crates')
-rw-r--r--crates/typst/src/foundations/array.rs34
1 files changed, 31 insertions, 3 deletions
diff --git a/crates/typst/src/foundations/array.rs b/crates/typst/src/foundations/array.rs
index 4c05e375..7d76cf5b 100644
--- a/crates/typst/src/foundations/array.rs
+++ b/crates/typst/src/foundations/array.rs
@@ -8,12 +8,12 @@ use ecow::{eco_format, EcoString, EcoVec};
use serde::{Deserialize, Serialize};
use smallvec::SmallVec;
-use crate::diag::{At, SourceResult, StrResult};
+use crate::diag::{bail, At, SourceResult, StrResult};
use crate::engine::Engine;
use crate::eval::ops;
use crate::foundations::{
- cast, func, repr, scope, ty, Args, Bytes, CastInfo, Context, FromValue, Func,
- IntoValue, Reflect, Repr, Value, Version,
+ cast, func, repr, scope, ty, Args, Bytes, CastInfo, Context, Dict, FromValue, Func,
+ IntoValue, Reflect, Repr, Str, Value, Version,
};
use crate::syntax::Span;
@@ -854,6 +854,34 @@ impl Array {
Ok(Self(out))
}
+
+ /// Converts an array of pairs into a dictionary.
+ /// The first value of each pair is the key, the second the value.
+ ///
+ /// If the same key occurs multiple times, the last value is selected.
+ ///
+ /// ```example
+ /// (("apples", 2), ("peaches", 3), ("apples", 5)).to-dict()
+ /// ```
+ #[func]
+ pub fn to_dict(self) -> StrResult<Dict> {
+ self.into_iter()
+ .map(|value| {
+ let value_ty = value.ty();
+ let pair = value.cast::<Array>().map_err(|_| {
+ eco_format!("expected (str, any) pairs, found {}", value_ty)
+ })?;
+ if let [key, value] = pair.as_slice() {
+ let key = key.clone().cast::<Str>().map_err(|_| {
+ eco_format!("expected key of type str, found {}", value.ty())
+ })?;
+ Ok((key, value.clone()))
+ } else {
+ bail!("expected pairs of length 2, found length {}", pair.len());
+ }
+ })
+ .collect()
+ }
}
/// A value that can be cast to bytes.