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}