wp_self_update/
versioning.rs1use crate::error::{integrity_check_failed, invalid_request, UpdateResult};
2use crate::types::VersionRelation;
3use semver::Version;
4
5pub(crate) fn parse_version(raw: &str) -> UpdateResult<Version> {
6 let normalized = raw.trim().trim_start_matches('v');
7 Version::parse(normalized)
8 .map_err(|e| invalid_request(format!("invalid semver '{}': {}", raw, e)))
9}
10
11pub(crate) fn compare_versions(current: &Version, latest: &Version) -> VersionRelation {
12 if latest > current {
13 return VersionRelation::UpdateAvailable;
14 }
15 if latest == current {
16 return VersionRelation::UpToDate;
17 }
18 VersionRelation::AheadOfChannel
19}
20
21pub fn compare_versions_str(current: &str, latest: &str) -> UpdateResult<VersionRelation> {
22 let current_version = parse_version(current)?;
23 let latest_version = parse_version(latest)?;
24 Ok(compare_versions(¤t_version, &latest_version))
25}
26
27pub fn validate_artifact_version_consistency(version: &str, artifact: &str) -> UpdateResult<()> {
28 if artifact.contains(version) {
29 return Ok(());
30 }
31 Err(integrity_check_failed(format!(
32 "artifact/version mismatch: artifact '{}' does not contain version '{}'",
33 artifact, version
34 )))
35}
36
37pub fn relation_message(relation: VersionRelation) -> &'static str {
38 match relation {
39 VersionRelation::UpdateAvailable => "update available",
40 VersionRelation::UpToDate => "up-to-date",
41 VersionRelation::AheadOfChannel => "ahead of channel manifest",
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48
49 #[test]
50 fn parse_version_accepts_v_prefix() {
51 let parsed = parse_version("v0.19.0-alpha.3").unwrap();
52 assert_eq!(parsed.to_string(), "0.19.0-alpha.3");
53 }
54
55 #[test]
56 fn compare_versions_update_available() {
57 let current = Version::parse("0.18.0").unwrap();
58 let latest = Version::parse("0.19.0").unwrap();
59 assert_eq!(
60 compare_versions(¤t, &latest),
61 VersionRelation::UpdateAvailable
62 );
63 }
64
65 #[test]
66 fn compare_versions_up_to_date() {
67 let current = Version::parse("0.19.0").unwrap();
68 let latest = Version::parse("0.19.0").unwrap();
69 assert_eq!(
70 compare_versions(¤t, &latest),
71 VersionRelation::UpToDate
72 );
73 }
74
75 #[test]
76 fn compare_versions_ahead_of_channel() {
77 let current = Version::parse("0.19.0").unwrap();
78 let latest = Version::parse("0.15.3").unwrap();
79 assert_eq!(
80 compare_versions(¤t, &latest),
81 VersionRelation::AheadOfChannel
82 );
83 }
84}