facti_lib/
semver.rs

1use crate::{
2    error::{ParseOpError, ParseVersionReqError, ParseVersionSpecError},
3    FactorioVersion,
4};
5
6use super::version::{Op, Version, VersionReq, VersionSpec};
7
8impl From<semver::Version> for Version {
9    fn from(value: semver::Version) -> Self {
10        Self {
11            major: value.major,
12            minor: value.minor,
13            patch: value.patch,
14        }
15    }
16}
17
18impl From<Version> for semver::Version {
19    fn from(value: Version) -> Self {
20        Self::new(value.major, value.minor, value.patch)
21    }
22}
23
24impl From<FactorioVersion> for semver::Version {
25    fn from(value: FactorioVersion) -> Self {
26        let version = Version::new(value.major, value.minor, value.patch.unwrap_or(0));
27        version.into()
28    }
29}
30
31impl From<FactorioVersion> for semver::VersionReq {
32    fn from(value: FactorioVersion) -> Self {
33        let version = semver::Version::from(value);
34        semver::VersionReq {
35            comparators: vec![semver::Comparator {
36                op: semver::Op::GreaterEq,
37                major: version.major,
38                minor: Some(version.minor),
39                patch: Some(version.patch),
40                pre: semver::Prerelease::EMPTY,
41            }],
42        }
43    }
44}
45
46impl TryFrom<semver::Op> for Op {
47    type Error = ParseOpError;
48
49    fn try_from(value: semver::Op) -> Result<Self, Self::Error> {
50        match value {
51            semver::Op::Exact => Ok(Op::Exact),
52            semver::Op::Greater => Ok(Op::Greater),
53            semver::Op::GreaterEq => Ok(Op::GreaterEq),
54            semver::Op::Less => Ok(Op::Less),
55            semver::Op::LessEq => Ok(Op::LessEq),
56            _ => Err(ParseOpError::Op(value)),
57        }
58    }
59}
60
61impl From<Op> for semver::Op {
62    fn from(value: Op) -> Self {
63        match value {
64            Op::Exact => semver::Op::Exact,
65            Op::Greater => semver::Op::Greater,
66            Op::GreaterEq => semver::Op::GreaterEq,
67            Op::Less => semver::Op::Less,
68            Op::LessEq => semver::Op::LessEq,
69        }
70    }
71}
72
73impl TryFrom<semver::VersionReq> for VersionReq {
74    type Error = ParseVersionReqError;
75
76    fn try_from(value: semver::VersionReq) -> Result<Self, Self::Error> {
77        if value == semver::VersionReq::STAR {
78            return Ok(VersionReq::Latest);
79        }
80        if value.comparators.is_empty() {
81            return Ok(VersionReq::Latest);
82        }
83
84        let spec = value.try_into()?;
85
86        Ok(VersionReq::Spec(spec))
87    }
88}
89
90impl From<VersionReq> for semver::VersionReq {
91    fn from(value: VersionReq) -> Self {
92        match value {
93            VersionReq::Latest => semver::VersionReq::STAR,
94            VersionReq::Spec(spec) => spec.into(),
95        }
96    }
97}
98
99impl TryFrom<semver::VersionReq> for VersionSpec {
100    type Error = ParseVersionSpecError;
101
102    fn try_from(value: semver::VersionReq) -> Result<Self, Self::Error> {
103        if value.comparators.is_empty() {
104            return Err(ParseVersionSpecError::SemverReqMissingComparator);
105        }
106
107        if value.comparators.len() > 1 {
108            return Err(ParseVersionSpecError::SemverReqTooManyComparators);
109        }
110
111        let comp = &value.comparators[0];
112        let op = comp.op.try_into()?;
113        let major = comp.major;
114        let minor = comp.minor.ok_or(ParseVersionSpecError::Minor)?;
115        let patch = comp.patch.ok_or(ParseVersionSpecError::Patch)?;
116        let version = Version::new(major, minor, patch);
117        Ok(VersionSpec { op, version })
118    }
119}
120
121impl From<VersionSpec> for semver::VersionReq {
122    fn from(value: VersionSpec) -> Self {
123        semver::VersionReq {
124            comparators: vec![semver::Comparator {
125                op: value.op.into(),
126                major: value.version.major,
127                minor: Some(value.version.minor),
128                patch: Some(value.version.patch),
129                pre: semver::Prerelease::EMPTY,
130            }],
131        }
132    }
133}