Repository: typst/typst
File: crates/typst-syntax/src/package.rs (Rust)

Code before:
}

impl PackageVersion {
    // the code in this impl block is based on https://github.com/dtolnay/semver/blob/1.0.23/src/eval.rs
    // author: David Tolnay <https://github.com/dtolnay>
    // licensed under Apache 2.0

    /// Performs an `==` match with the given version bound. Version elements missing in the bound
    /// are ignored.
    ///
    /// ```
    /// # use typst_syntax::package::{PackageVersion, SemVerBound};
    /// # use std::str::FromStr;
    /// let v1_1_1 = PackageVersion::from_str("1.1.1").unwrap();
    ///
    /// assert!(!v1_1_1.matches_eq(&SemVerBound::from_str("0").unwrap()));
    /// assert!(v1_1_1.matches_eq(&SemVerBound::from_str("1").unwrap()));
    /// assert!(!v1_1_1.matches_eq(&SemVerBound::from_str("2").unwrap()));
    ///
    /// assert!(!v1_1_1.matches_eq(&SemVerBound::from_str("1.0").unwrap()));
    /// assert!(v1_1_1.matches_eq(&SemVerBound::from_str("1.1").unwrap()));
    /// assert!(!v1_1_1.matches_eq(&SemVerBound::from_str("1.2").unwrap()));
    ///
    /// assert!(!v1_1_1.matches_eq(&SemVerBound::from_str("1.1.0").unwrap()));
    /// assert!(v1_1_1.matches_eq(&SemVerBound::from_str("1.1.1").unwrap()));
    /// assert!(!v1_1_1.matches_eq(&SemVerBound::from_str("1.1.2").unwrap()));
    /// ```
    pub fn matches_eq(&self, bound: &SemVerBound) -> bool {
        if self.major != bound.major {
            return false;
        }
        if bound.minor.map_or(false, |minor| self.minor != minor) {
            return false;
        }
        if bound.patch.map_or(false, |patch| self.patch != patch) {
            return false;
        }
        true
    }

    /// Performs a `>` match with the given version bound. The match only succeeds if some version
    /// element in the bound is actually greater than that of the version.
    ///
    /// ```
    /// # use typst_syntax::package::{PackageVersion, SemVerBound};
    /// # use std::str::FromStr;
    /// let v1_1_1 = PackageVersion::from_str("1.1.1").unwrap();
    ///
    /// assert!(v1_1_1.matches_gt(&SemVerBound::from_str("0").unwrap()));
    /// assert!(!v1_1_1.matches_gt(&SemVerBound::from_str("1").unwrap()));
    /// assert!(!v1_1_1.matches_gt(&SemVerBound::from_str("2").unwrap()));

Review comment (performance):
The doc tests are a bit much imo. The total PR diff is a lot of lines for such a small thing. Also doc tests are slow to compile. I'd prefer a few (like ten assertions) in a `#[cfg(test)]` module at the bottom.

Code after:

    /// Performs an `==` match with the given version bound. Version elements
    /// missing in the bound are ignored.
    pub fn matches_eq(&self, bound: &VersionBound) -> bool {
        self.major == bound.major
            && bound.minor.map_or(true, |minor| self.minor == minor)
            && bound.patch.map_or(true, |patch| self.patch == patch)
    }

    /// Performs a `>` match with the given version bound. The match only
    /// succeeds if some version element in the bound is actually greater than
    /// that of the version.
    pub fn matches_gt(&self, bound: &VersionBound) -> bool {
        if self.major != bound.major {
            return self.major > bound.major;
        }
        let Some(minor) = bound.minor else { return false };
        if self.minor != minor {
            return self.minor > minor;
        }
        let Some(patch) = bound.patch else { return false };
        if self.patch != patch {
            return self.patch > patch;
        }
        false
    }

    /// Performs a `<` match with the given version bound. The match only
    /// succeeds if some version element in the bound is actually less than that
    /// of the version.
    pub fn matches_lt(&self, bound: &VersionBound) -> bool {
        if self.major != bound.major {
            return self.major < bound.major;
        }
        let Some(minor) = bound.minor else { return false };
        if self.minor != minor {
            return self.minor < minor;
        }
        let Some(patch) = bound.patch else { return false };
        if self.patch != patch {
            return self.patch < patch;
        }
        false
    }

    /// Performs a `>=` match with the given versions. The match succeeds when
    /// either a `==` or `>` match does.
    pub fn matches_ge(&self, bound: &VersionBound) -> bool {
        self.matches_eq(bound) || self.matches_gt(bound)
    }