Repository: typst/typst
File: crates/typst/src/foundations/int.rs (Rust)

Code before:
                // Reference:
                // https://doc.rust-lang.org/stable/reference/expressions/operator-expr.html#numeric-cast
                ((self as u64) >> shift) as i64
            }
        } else {
            // Saturate at -1 (negative) or 0 (otherwise) on excessive arithmetic
            // right shift. Shifting those numbers any further does not change
            // them, so it is consistent.
            let shift = shift.min(i64::BITS - 1);
            self >> shift
        }
    }

    /// Converts bytes to an integer.
    /// Bytes should be 8 bytes (64 bits) in size.
    ///
    /// ```example
    /// #int.from-bytes(bytes((0, 0, 0, 0, 0, 0, 0, 1)), "little")
    /// ```
    #[func]
    pub fn from_bytes(
        /// The bytes that should be converted to an integer.
        bytes: Bytes,
        /// Endianness
        /// - Little endian: the bytes are interpreted from the least significant to the most significant.
        /// - Big endian: the bytes are interpreted from the most significant to the least significant.
        endianness: Endianness,
    ) -> Result<i64, EcoString> {
        let array: [u8; 8] =
            bytes.as_ref().try_into().map_err(|_| "Bytes should have size 8")?;
        match endianness {
            Endianness::Big => Ok(i64::from_be_bytes(array)),
            Endianness::Little => Ok(i64::from_le_bytes(array)),
        }
    }

    /// Converts an integer to bytes.
    /// The integer is converted to 8 bytes or 64 bits in size.
    ///
    /// ```example
    /// #array(10000.to-bytes("big"))
    /// ```
    #[func]
    pub fn to_bytes(
        self,
        /// Endianness
        /// - Little endian: the bytes are interpreted from the least significant to the most significant.
        /// - Big endian: the bytes are interpreted from the most significant to the least significant.
        endianness: Endianness,
    ) -> Bytes {
        let array = match endianness {

Review comment (suggestion):
Seems this document does not tell users how to specify the endianness? I would suggest clearly document the acceptable strings here, instead of indicating them in examples.

Code after:
                // two integers of same size (i64 <-> u64) is a no-op (two's complement
                // is used).
                // Reference:
                // https://doc.rust-lang.org/stable/reference/expressions/operator-expr.html#numeric-cast
                ((self as u64) >> shift) as i64
            }
        } else {
            // Saturate at -1 (negative) or 0 (otherwise) on excessive arithmetic
            // right shift. Shifting those numbers any further does not change
            // them, so it is consistent.
            let shift = shift.min(i64::BITS - 1);
            self >> shift
        }
    }

    /// Converts bytes to an integer.
    ///
    /// ```example
    /// #int.from-bytes(bytes((0, 0, 0, 0, 0, 0, 0, 1))) \
    /// #int.from-bytes(bytes((1, 0, 0, 0, 0, 0, 0, 0)), endian: "big")
    /// ```
    #[func]
    pub fn from_bytes(
        /// The bytes that should be converted to an integer.
        ///
        /// Must be of length at most 8 so that the result fits into a 64-bit
        /// signed integer.
        bytes: Bytes,
        /// The endianness of the conversion.
        #[named]
        #[default(Endianness::Little)]
        endian: Endianness,
        /// Whether the bytes should be treated as a signed integer. If this is
        /// `{true}` and the most significant bit is set, the resulting number
        /// will negative.
        #[named]
        #[default(true)]
        signed: bool,
    ) -> StrResult<i64> {
        let len = bytes.len();
        if len == 0 {
            return Ok(0);
        } else if len > 8 {
            bail!("too many bytes to convert to a 64 bit number");
        }

        // `decimal` will hold the part of the buffer that should be filled with
        // the input bytes, `rest` will remain as is or be filled with 0xFF for
        // negative numbers if signed is true.
        //
        // – big-endian: `decimal` will be the rightmost bytes of the buffer.