diff options
| author | frozolotl <44589151+frozolotl@users.noreply.github.com> | 2024-04-01 19:21:19 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-01 17:21:19 +0000 |
| commit | 82717b28694d56a25f1bcb381258073255ef74cd (patch) | |
| tree | dcbf849992c62d01e1353820d33ea1479c322bdb /crates | |
| parent | 27259b714f4fe0f3c7cf877333f303e562680c76 (diff) | |
Implement `to-dict` method on arrays (#3575)
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/typst/src/foundations/array.rs | 34 |
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. |
