diff options
| author | f3rn0s <ffc@null.net> | 2024-02-20 23:55:06 +1000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-20 13:55:06 +0000 |
| commit | f1495de8bb6414fa6fe4da27c5a5b2cd3dd53cfa (patch) | |
| tree | 892f188369b888e7fdab9b12066c1d6c34e1e18c | |
| parent | b3ed2df27e7822fcb401b5444392973027e188c7 (diff) | |
Add module -> dictionary conversion (#3428)
Co-authored-by: f3rn0s <finn@volkis.com.au>
Co-authored-by: Laurenz <laurmaedje@gmail.com>
Co-authored-by: Ilia <43654815+istudyatuni@users.noreply.github.com>
| -rw-r--r-- | crates/typst/src/foundations/dict.rs | 29 | ||||
| -rw-r--r-- | tests/typ/compiler/dict.typ | 5 |
2 files changed, 33 insertions, 1 deletions
diff --git a/crates/typst/src/foundations/dict.rs b/crates/typst/src/foundations/dict.rs index 06c8f0e4..e77d33ff 100644 --- a/crates/typst/src/foundations/dict.rs +++ b/crates/typst/src/foundations/dict.rs @@ -8,7 +8,9 @@ use indexmap::IndexMap; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use crate::diag::{Hint, HintedStrResult, StrResult}; -use crate::foundations::{array, func, repr, scope, ty, Array, Repr, Str, Value}; +use crate::foundations::{ + array, cast, func, repr, scope, ty, Array, Module, Repr, Str, Value, +}; use crate::syntax::is_ident; use crate::util::ArcExt; @@ -158,6 +160,23 @@ impl Dict { #[scope] impl Dict { + /// Converts a value into a dictionary. + /// + /// Note that this function is only intended for conversion of a + /// dictionary-like value to a dictionary, not for creation of a dictionary + /// from individual pairs. Use the dictionary syntax `(key: value)` instead. + /// + /// ```example + /// #dictionary(sys).at("version") + /// ``` + #[func(constructor)] + pub fn construct( + /// The value that should be converted to a dictionary. + value: ToDict, + ) -> Dict { + value.0 + } + /// The number of pairs in the dictionary. #[func(title = "Length")] pub fn len(&self) -> usize { @@ -237,6 +256,14 @@ impl Dict { } } +/// A value that can be cast to dictionary. +pub struct ToDict(Dict); + +cast! { + ToDict, + v: Module => Self(v.scope().iter().map(|(k, v)| (Str::from(k.clone()), v.clone())).collect()), +} + impl Debug for Dict { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_map().entries(self.0.iter()).finish() diff --git a/tests/typ/compiler/dict.typ b/tests/typ/compiler/dict.typ index eca1c458..8a5be5cd 100644 --- a/tests/typ/compiler/dict.typ +++ b/tests/typ/compiler/dict.typ @@ -84,6 +84,11 @@ #test(dict, (a: 3, b: 1)) --- +// Test dictionary constructor +#dictionary(sys).at("version") +#dictionary(sys).at("no_crash", default: none) + +--- // Test that removal keeps order. #let dict = (a: 1, b: 2, c: 3, d: 4) #dict.remove("b") |
