mirror of
https://github.com/typst/typst
synced 2025-05-22 04:55:29 +08:00
Implement to-dict
method on arrays (#3575)
This commit is contained in:
parent
27259b714f
commit
82717b2869
@ -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.
|
||||
|
@ -307,12 +307,34 @@
|
||||
#test(("Jane", "John", "Eric", "John").dedup(), ("Jane", "John", "Eric"))
|
||||
|
||||
---
|
||||
// Test the `dedup` with the `key` argument.
|
||||
// Test the `dedup` method with the `key` argument.
|
||||
#test((1, 2, 3, 4, 5, 6).dedup(key: x => calc.rem(x, 2)), (1, 2))
|
||||
#test((1, 2, 3, 4, 5, 6).dedup(key: x => calc.rem(x, 3)), (1, 2, 3))
|
||||
#test(("Hello", "World", "Hi", "There").dedup(key: x => x.len()), ("Hello", "Hi"))
|
||||
#test(("Hello", "World", "Hi", "There").dedup(key: x => x.at(0)), ("Hello", "World", "There"))
|
||||
|
||||
---
|
||||
// Test the `to-dict` method.
|
||||
#test(().to-dict(), (:))
|
||||
#test((("a", 1), ("b", 2), ("c", 3)).to-dict(), (a: 1, b: 2, c: 3))
|
||||
#test((("a", 1), ("b", 2), ("c", 3), ("b", 4)).to-dict(), (a: 1, b: 4, c: 3))
|
||||
|
||||
---
|
||||
// Error: 2-16 expected (str, any) pairs, found integer
|
||||
#(1,).to-dict()
|
||||
|
||||
---
|
||||
// Error: 2-19 expected pairs of length 2, found length 1
|
||||
#((1,),).to-dict()
|
||||
|
||||
---
|
||||
// Error: 2-26 expected pairs of length 2, found length 3
|
||||
#(("key",1,2),).to-dict()
|
||||
|
||||
---
|
||||
// Error: 2-21 expected key of type str, found integer
|
||||
#((1, 2),).to-dict()
|
||||
|
||||
---
|
||||
// Error: 9-26 unexpected argument: val
|
||||
#().zip(val: "applicable")
|
||||
|
Loading…
x
Reference in New Issue
Block a user