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

Code before:
    ///   (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,
        engine: &mut Engine,
        context: Tracked<Context>,
        span: Span,
        /// If given, applies this function to the elements in the array to
        /// determine the keys to sort by.
        #[named]
        key: Option<Func>,
        /// If given, uses this function to compare elements in the array.
        ///
        /// This function should return a boolean: `{true}` indicates that the
        /// elements are in order, while `{false}` indicates that they should be
        /// swapped. To keep the sort stable, if the two elements are equal, the
        /// function should return `{true}`.
        ///
        /// If this function does not order the elements properly (e.g., by
        /// returning `{false}` for both `{(x, y)}` and `{(y, x)}`), the
        /// resulting array will be unspecified order.
        ///
        /// When used together with `key`, `by` will be passed the keys instead
        /// of the elements.
        ///
        /// ```example
        /// #(
        ///   "sorted",
        ///   "by",
        ///   "decreasing",
        ///   "length",
        /// ).sorted(
        ///   key: s => s.len(),
        ///   by: (l, r) => l >= r,
        /// )
        /// ```
        #[named]
        by: Option<Func>,
    ) -> SourceResult<Array> {
        let mut are_in_order = |mut x: Value, mut y: Value| {
            if let Some(f) = &key {
                x = f.call(engine, context, [x])?;
                y = f.call(engine, context, [y])?;
            }
            match &by {
                Some(f) => match f.call(engine, context, [x, y])? {

Review comment (suggestion):
```suggestion
        /// resulting array will be in unspecified order.
```

Code after:
    ///   (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,
        engine: &mut Engine,
        context: Tracked<Context>,
        span: Span,
        /// If given, applies this function to the elements in the array to
        /// determine the keys to sort by.
        #[named]
        key: Option<Func>,
        /// If given, uses this function to compare elements in the array.
        ///
        /// This function should return a boolean: `{true}` indicates that the
        /// elements are in order, while `{false}` indicates that they should be
        /// swapped. To keep the sort stable, if the two elements are equal, the
        /// function should return `{true}`.
        ///
        /// If this function does not order the elements properly (e.g., by
        /// returning `{false}` for both `{(x, y)}` and `{(y, x)}`, or for
        /// `{(x, x)}`), the resulting array will be in unspecified order.
        ///
        /// When used together with `key`, `by` will be passed the keys instead
        /// of the elements.
        ///
        /// ```example
        /// #(
        ///   "sorted",
        ///   "by",
        ///   "decreasing",
        ///   "length",
        /// ).sorted(
        ///   key: s => s.len(),
        ///   by: (l, r) => l >= r,
        /// )
        /// ```
        #[named]
        by: Option<Func>,
    ) -> SourceResult<Array> {
        match by {
            Some(by) => {
                let mut are_in_order = |mut x, mut y| {
                    if let Some(f) = &key {
                        // We rely on `comemo`'s memoization of function
                        // evaluation to not excessively reevaluate the key.
                        x = f.call(engine, context, [x])?;