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

Code before:
        self,
        /// How many elements each window will contain.
        window_size: NonZeroUsize,
    ) -> Array {
        self.0
            .windows(window_size.get())
            .map(|window| Array::from(window).into_value())
            .collect()
    }

    /// Return a sorted version of this array, optionally by a given key
    /// function. The sorting algorithm used is stable.
    ///
    /// Returns an error if two values could not be compared or if the key
    /// function (if given) yields an error.
    /// 
    /// The key function can return a tuple to sort by multiple keys.
    ///
    /// ```example
    /// #let array = (
    ///   (a: "foo", b: "baz"),
    ///   (a: "fizz", b: "buzz"),
    ///   (a: "foo", b: "bar"),
    /// )
    /// #array.sorted(key: it => (it.a, it.b))
    /// ```
    #[func]
    pub fn sorted(
        self,
        /// The engine.
        engine: &mut Engine,
        /// The callsite context.
        context: Tracked<Context>,
        /// The callsite span.
        span: Span,
        /// If given, applies this function to the elements in the array to
        /// determine the keys to sort by.
        #[named]
        key: Option<Func>,
    ) -> SourceResult<Array> {
        let mut result = Ok(());
        let mut vec = self.0;
        let mut key_of = |x: Value| match &key {
            // NOTE: We are relying on `comemo`'s memoization of function
            // evaluation to not excessively reevaluate the `key`.
            Some(f) => f.call(engine, context, [x]),
            None => Ok(x),
        };
        vec.make_mut().sort_by(|a, b| {
            // Until we get `try` blocks :)
            match (key_of(a.clone()), key_of(b.clone())) {

Review comment (suggestion):
Maybe the example should use numbers instead of strings, to make it clearer how the array gets sorted (tuples of integers are easier to compare than tuple of strings for human beings).

Code after:
        self,
        /// How many elements each window will contain.
        window_size: NonZeroUsize,
    ) -> Array {
        self.0
            .windows(window_size.get())
            .map(|window| Array::from(window).into_value())
            .collect()
    }

    /// Return a sorted version of this array, optionally by a given key
    /// function. The sorting algorithm used is stable.
    ///
    /// Returns an error if two values could not be compared or if the key
    /// function (if given) yields an error.
    ///
    /// To sort according to multiple criteria at once, e.g. in case of equality
    /// between some criteria, the key function can return an array. The results
    /// are in lexicographic order.
    ///
    /// ```example
    /// #let array = (
    ///   (a: 2, b: 4),
    ///   (a: 1, b: 5),
    ///   (a: 2, b: 3),
    /// )
    /// #array.sorted(key: it => (it.a, it.b))
    /// ```
    #[func]
    pub fn sorted(
        self,
        /// The engine.
        engine: &mut Engine,
        /// The callsite context.
        context: Tracked<Context>,
        /// The callsite span.
        span: Span,
        /// If given, applies this function to the elements in the array to
        /// determine the keys to sort by.
        #[named]
        key: Option<Func>,
    ) -> SourceResult<Array> {
        let mut result = Ok(());
        let mut vec = self.0;
        let mut key_of = |x: Value| match &key {
            // NOTE: We are relying on `comemo`'s memoization of function
            // evaluation to not excessively reevaluate the `key`.
            Some(f) => f.call(engine, context, [x]),
            None => Ok(x),
        };
        vec.make_mut().sort_by(|a, b| {