version.rs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // Copyright 2019-2022 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. //! Compare two semantic versions.
  5. //!
  6. //! [Semantic Versioning](https://semver.org) is a guideline for how version numbers are assigned and incremented.
  7. //! The functions on this module are helpers around [semver](https://docs.rs/semver/latest/semver/).
  8. use semver::Version;
  9. use std::cmp::Ordering;
  10. /// Compare two semver versions.
  11. ///
  12. /// If the `first` semver is greater, returns -1.
  13. /// If the `second` semver is greater, returns 1.
  14. /// If they are equal, returns 0.
  15. ///
  16. /// # Examples
  17. ///
  18. /// ```
  19. /// use tauri::api::version::compare;
  20. /// assert_eq!(compare("0.15.0", "0.15.5").unwrap(), 1);
  21. /// assert_eq!(compare("0.15.10", "0.15.9").unwrap(), -1);
  22. /// assert_eq!(compare("0.15.10", "0.16.10").unwrap(), 1);
  23. /// assert_eq!(compare("1.57.0", "2.17.4").unwrap(), 1);
  24. /// assert_eq!(compare("0.0.0", "0.0.0").unwrap(), 0);
  25. /// ```
  26. pub fn compare(first: &str, second: &str) -> crate::api::Result<i8> {
  27. let v1 = Version::parse(first)?;
  28. let v2 = Version::parse(second)?;
  29. match v1.cmp(&v2) {
  30. Ordering::Greater => Ok(-1),
  31. Ordering::Less => Ok(1),
  32. Ordering::Equal => Ok(0),
  33. }
  34. }
  35. /// Check if the "second" semver is compatible with the "first".
  36. ///
  37. /// # Examples
  38. ///
  39. /// ```
  40. /// use tauri::api::version::is_compatible;
  41. /// assert!(is_compatible("0.15.0", "0.15.5").unwrap());
  42. /// assert!(!is_compatible("0.15.0", "0.16.5").unwrap());
  43. ///
  44. /// assert!(is_compatible("1.5.0", "1.5.10").unwrap());
  45. /// assert!(is_compatible("1.54.0", "1.55.0").unwrap());
  46. /// assert!(!is_compatible("2.17.0", "3.17.0").unwrap());
  47. /// ```
  48. pub fn is_compatible(first: &str, second: &str) -> crate::api::Result<bool> {
  49. let first = Version::parse(first)?;
  50. let second = Version::parse(second)?;
  51. Ok(if second.major == 0 && first.major == 0 {
  52. first.minor == second.minor && second.patch > first.patch
  53. } else if second.major > 0 {
  54. first.major == second.major
  55. && ((second.minor > first.minor)
  56. || (first.minor == second.minor && second.patch > first.patch))
  57. } else {
  58. false
  59. })
  60. }
  61. /// Check if a the "other" version is a major bump from the "current".
  62. ///
  63. /// # Examples
  64. ///
  65. /// ```
  66. /// use tauri::api::version::is_major;
  67. /// assert!(is_major("1.0.0", "2.0.0").unwrap());
  68. /// assert!(is_major("1.5.0", "2.17.10").unwrap());
  69. /// assert!(is_major("0.5.0", "2.17.10").unwrap());
  70. /// assert!(!is_major("1.1.5", "1.2.5").unwrap());
  71. /// assert!(!is_major("0.14.0", "0.15.0").unwrap());
  72. /// ```
  73. pub fn is_major(current: &str, other: &str) -> crate::api::Result<bool> {
  74. let current = Version::parse(current)?;
  75. let other = Version::parse(other)?;
  76. Ok(other.major > current.major)
  77. }
  78. /// Check if a the "other" version is a minor bump from the "current".
  79. ///
  80. /// # Examples
  81. ///
  82. /// ```
  83. /// use tauri::api::version::is_minor;
  84. /// assert!(is_minor("0.15.10", "0.16.110").unwrap());
  85. /// assert!(is_minor("1.0.0", "1.1.1").unwrap());
  86. /// assert!(!is_minor("2.1.9", "3.2.0").unwrap());
  87. /// assert!(!is_minor("1.0.0", "1.0.10").unwrap());
  88. /// ```
  89. pub fn is_minor(current: &str, other: &str) -> crate::api::Result<bool> {
  90. let current = Version::parse(current)?;
  91. let other = Version::parse(other)?;
  92. Ok(current.major == other.major && other.minor > current.minor)
  93. }
  94. /// Check if a the "other" version is a patch bump from the "current".
  95. ///
  96. /// # Examples
  97. ///
  98. /// ```
  99. /// use tauri::api::version::is_patch;
  100. /// assert!(is_patch("0.15.0", "0.15.1").unwrap());
  101. /// assert!(is_patch("1.0.0", "1.0.1").unwrap());
  102. /// assert!(!is_patch("2.2.0", "2.3.1").unwrap());
  103. /// assert!(!is_patch("2.2.1", "1.1.0").unwrap());
  104. /// ```
  105. pub fn is_patch(current: &str, other: &str) -> crate::api::Result<bool> {
  106. let current = Version::parse(current)?;
  107. let other = Version::parse(other)?;
  108. Ok(current.major == other.major && current.minor == other.minor && other.patch > current.patch)
  109. }
  110. /// Check if a version is greater than the current.
  111. ///
  112. /// # Examples
  113. ///
  114. /// ```
  115. /// use tauri::api::version::is_greater;
  116. /// assert!(is_greater("0.15.10", "0.16.0").unwrap());
  117. /// assert!(is_greater("1.0.0", "1.0.1").unwrap());
  118. /// assert!(is_greater("1.1.9", "1.2.0").unwrap());
  119. /// assert!(is_greater("1.0.0", "2.0.0").unwrap());
  120. /// ```
  121. pub fn is_greater(current: &str, other: &str) -> crate::api::Result<bool> {
  122. Ok(Version::parse(other)? > Version::parse(current)?)
  123. }