Repository: typst/typst
File: crates/typst-library/src/foundations/dict.rs (Rust)

Code before:

    /// Returns the keys of the dictionary as an array in insertion order.
    #[func]
    pub fn keys(&self) -> Array {
        self.0.keys().cloned().map(Value::Str).collect()
    }

    /// Returns the values of the dictionary as an array in insertion order.
    #[func]
    pub fn values(&self) -> Array {
        self.0.values().cloned().collect()
    }

    /// Returns the keys and values of the dictionary as an array of pairs. Each
    /// pair is represented as an array of length two.
    #[func]
    pub fn pairs(&self) -> Array {
        self.0
            .iter()
            .map(|(k, v)| Value::Array(array![k.clone(), v.clone()]))
            .collect()
    }

    /// Produces a new dictionary with only the pairs from the original one for
    /// which the value passes test.
    ///
    /// ```example
    /// #{
    ///   (a: 0, b: 1, c: 2)
    ///     .filter(v => v > 0)
    /// }
    /// ```
    #[func]
    pub fn filter(
        self,
        engine: &mut Engine,
        context: Tracked<Context>,
        /// The function to apply to each value. Must return a boolean.
        test: Func,
    ) -> SourceResult<Dict> {
        let mut run_test = |v: &Value| {
            test.call(engine, context, [v.clone()])?
                .cast::<bool>()
                .at(test.span())
        };
        self.into_iter()
            .filter_map(|(k, v)| run_test(&v).map(|b| b.then_some((k, v))).transpose())
            .collect()
    }

    /// Produces a new dictionary where the keys are the same, but the values

Review comment (suggestion):
Maybe we want to add a second example here for how to filter pairs with `.pairs()` and `.to-dict()`? and same for `map`.

Code after:

    /// Returns the keys of the dictionary as an array in insertion order.
    #[func]
    pub fn keys(&self) -> Array {
        self.0.keys().cloned().map(Value::Str).collect()
    }

    /// Returns the values of the dictionary as an array in insertion order.
    #[func]
    pub fn values(&self) -> Array {
        self.0.values().cloned().collect()
    }

    /// Returns the keys and values of the dictionary as an array of pairs. Each
    /// pair is represented as an array of length two.
    #[func]
    pub fn pairs(&self) -> Array {
        self.0
            .iter()
            .map(|(k, v)| Value::Array(array![k.clone(), v.clone()]))
            .collect()
    }

    /// Produces a new dictionary with only the pairs from the original one for
    /// which the given function returns `{true}`.
    ///
    /// ```example:"Basic usage"
    /// #{
    ///   (a: 0, b: 1, c: 2)
    ///     .filter(v => v > 0)
    /// }
    /// ```
    ///
    /// ```example:"Filtering based on the key instead of the value"
    /// #{
    ///   (a: 0, b: 1, c: 2)
    ///     .pairs()
    ///     .filter(((k, v)) => k != "a")
    ///     .to-dict()
    /// }
    /// ```
    #[func]
    pub fn filter(
        self,
        engine: &mut Engine,
        context: Tracked<Context>,
        /// The function to apply to each value. Must return a boolean.
        test: Func,
    ) -> SourceResult<Dict> {
        let mut run_test = |v: &Value| {
            test.call(engine, context, [v.clone()])?