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

Code before:
    /// The divisor of the remainder.
    divisor: Spanned<DecNum>,
) -> SourceResult<DecNum> {
    if divisor.v.is_zero() {
        bail!(divisor.span, "divisor must not be zero");
    }

    dividend
        .apply2(
            divisor.v,
            |a, b| a.checked_rem(b).map(DecNum::Int),
            |a, b| Some(DecNum::Float(a % b)),
            |a, b| a.checked_rem(b).map(DecNum::Decimal),
        )
        .ok_or_else(cant_apply_to_decimal_and_float)
        .at(span)?
        .ok_or("dividend too small compared to divisor")
        .at(span)
}

/// Performs euclidean division of two numbers.
///
/// The result of this computation is that of a division rounded to the integer
/// `{n}` such that the dividend is greater than or equal to `{n}` times the divisor.
///
/// This can error if the dividend is too small in magnitude compared to the divisor.
///
/// ```example
/// #calc.div-euclid(7, 3) \
/// #calc.div-euclid(7, -3) \
/// #calc.div-euclid(-7, 3) \
/// #calc.div-euclid(-7, -3) \
/// #calc.div-euclid(1.75, 0.5) \
/// #calc.div-euclid(decimal("1.75"), decimal("0.5"))
/// ```
#[func(title = "Euclidean Division")]
pub fn div_euclid(
    span: Span,
    /// The dividend of the division.
    dividend: DecNum,
    /// The divisor of the division.
    divisor: Spanned<DecNum>,
) -> SourceResult<DecNum> {
    if divisor.v.is_zero() {
        bail!(divisor.span, "divisor must not be zero");
    }

    dividend
        .apply2(
            divisor.v,
            |a, b| a.checked_div_euclid(b).map(DecNum::Int),

Review comment (suggestion):
This seems more accurate for this function.
```suggestion
/// This can error if the resulting number is larger than the maximum value or
/// smaller than the minimum value for its type.
```

Code after:
pub fn rem(
    span: Span,
    /// The dividend of the remainder.
    dividend: DecNum,
    /// The divisor of the remainder.
    divisor: Spanned<DecNum>,
) -> SourceResult<DecNum> {
    if divisor.v.is_zero() {
        bail!(divisor.span, "divisor must not be zero");
    }

    dividend
        .apply2(
            divisor.v,
            // `checked_rem` can only overflow on `i64::MIN % -1` which is
            // mathematically zero.
            |a, b| Some(DecNum::Int(a.checked_rem(b).unwrap_or(0))),
            |a, b| Some(DecNum::Float(a % b)),
            |a, b| a.checked_rem(b).map(DecNum::Decimal),
        )
        .ok_or_else(cant_apply_to_decimal_and_float)
        .at(span)?
        .ok_or("dividend too small compared to divisor")
        .at(span)
}

/// Performs euclidean division of two numbers.
///
/// The result of this computation is that of a division rounded to the integer
/// `{n}` such that the dividend is greater than or equal to `{n}` times
/// the divisor.
///
/// This can error if the resulting number is larger than the maximum value or
/// smaller than the minimum value for its type.
///
/// ```example
/// #calc.div-euclid(7, 3) \
/// #calc.div-euclid(7, -3) \
/// #calc.div-euclid(-7, 3) \
/// #calc.div-euclid(-7, -3) \
/// #calc.div-euclid(1.75, 0.5) \
/// #calc.div-euclid(decimal("1.75"), decimal("0.5"))
/// ```
#[func(title = "Euclidean Division")]
pub fn div_euclid(
    span: Span,
    /// The dividend of the division.
    dividend: DecNum,
    /// The divisor of the division.
    divisor: Spanned<DecNum>,
) -> SourceResult<DecNum> {