Skip to content

Commit e20cbbd

Browse files
authored
Support for v5 dependencies / incompatibilities (#54)
* implement dependency parsing for v5 * add breaking / required in dependency / incompat responses
2 parents 97f18e9 + 7851177 commit e20cbbd

3 files changed

Lines changed: 107 additions & 14 deletions

File tree

src/types/mod_json.rs

Lines changed: 100 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,30 @@ pub enum ModJsonDependencyType {
7878
}
7979

8080
#[derive(Deserialize, Debug)]
81-
pub struct ModJsonDependency {
81+
pub struct ModJsonDependencyOnlyVersion {
82+
version: String,
83+
}
84+
85+
#[derive(Deserialize, Debug)]
86+
pub struct ModJsonDependencyWithImportance {
8287
version: String,
83-
#[serde(default)]
8488
importance: DependencyImportance,
8589
}
8690

91+
#[derive(Deserialize, Debug)]
92+
pub struct ModJsonDependencyWithRequired {
93+
version: String,
94+
required: bool,
95+
}
96+
97+
#[derive(Deserialize, Debug)]
98+
#[serde(untagged)]
99+
pub enum ModJsonDependency {
100+
WithImportance(ModJsonDependencyWithImportance),
101+
WithRequired(ModJsonDependencyWithRequired),
102+
OnlyVersion(ModJsonDependencyOnlyVersion),
103+
}
104+
87105
#[derive(Deserialize, Debug)]
88106
pub struct OldModJsonDependency {
89107
pub id: String,
@@ -107,10 +125,27 @@ pub enum ModJsonIncompatibilityType {
107125
}
108126

109127
#[derive(Deserialize, Debug)]
110-
pub struct ModJsonIncompatibility {
128+
pub struct ModJsonIncompatibilityOnlyVersion {
111129
version: String,
112-
#[serde(default)]
113-
pub importance: IncompatibilityImportance,
130+
}
131+
132+
#[derive(Deserialize, Debug)]
133+
pub struct ModJsonIncompatibilityWithImportance {
134+
version: String,
135+
importance: IncompatibilityImportance,
136+
}
137+
138+
#[derive(Deserialize, Debug)]
139+
pub struct ModJsonIncompatibilityWithBreaking {
140+
version: String,
141+
breaking: bool,
142+
}
143+
144+
#[derive(Deserialize, Debug)]
145+
pub enum ModJsonIncompatibility {
146+
WithImportance(ModJsonIncompatibilityWithImportance),
147+
WithBreaking(ModJsonIncompatibilityWithBreaking),
148+
OnlyVersion(ModJsonIncompatibilityOnlyVersion),
114149
}
115150

116151
#[derive(Deserialize, Debug)]
@@ -250,18 +285,33 @@ impl ModJson {
250285
});
251286
}
252287
ModJsonDependencyType::Detailed(detailed) => {
253-
let (dependency_ver, compare) =
254-
split_version_and_compare(&(detailed.version)).map_err(|_| {
288+
let (dep_ver, importance) = match detailed {
289+
ModJsonDependency::OnlyVersion(data) => {
290+
(&data.version, DependencyImportance::default())
291+
}
292+
ModJsonDependency::WithRequired(data) => (
293+
&data.version,
294+
match data.required {
295+
true => DependencyImportance::Required,
296+
false => DependencyImportance::Recommended,
297+
},
298+
),
299+
ModJsonDependency::WithImportance(data) => {
300+
(&data.version, data.importance)
301+
}
302+
};
303+
let (dependency_ver, compare) = split_version_and_compare(dep_ver)
304+
.map_err(|_| {
255305
ModZipError::InvalidModJson(format!(
256306
"Invalid semver {}",
257-
detailed.version
307+
dep_ver
258308
))
259309
})?;
260310
ret.push(DependencyCreate {
261311
dependency_id: id.clone(),
262312
version: dependency_ver.to_string(),
263313
compare,
264-
importance: detailed.importance,
314+
importance,
265315
});
266316
}
267317
}
@@ -336,18 +386,33 @@ impl ModJson {
336386
});
337387
}
338388
ModJsonIncompatibilityType::Detailed(detailed) => {
339-
let (ver, compare) = split_version_and_compare(&(detailed.version))
340-
.map_err(|_| {
389+
let (inc_ver, importance) = match detailed {
390+
ModJsonIncompatibility::OnlyVersion(data) => {
391+
(&data.version, IncompatibilityImportance::default())
392+
}
393+
ModJsonIncompatibility::WithBreaking(data) => (
394+
&data.version,
395+
match data.breaking {
396+
true => IncompatibilityImportance::Breaking,
397+
false => IncompatibilityImportance::Conflicting,
398+
},
399+
),
400+
ModJsonIncompatibility::WithImportance(data) => {
401+
(&data.version, data.importance)
402+
}
403+
};
404+
let (ver, compare) =
405+
split_version_and_compare(inc_ver).map_err(|_| {
341406
ModZipError::InvalidModJson(format!(
342407
"Invalid semver {}",
343-
detailed.version
408+
inc_ver
344409
))
345410
})?;
346411
ret.push(IncompatibilityCreate {
347412
incompatibility_id: id.clone(),
348413
version: ver.to_string(),
349414
compare,
350-
importance: detailed.importance,
415+
importance,
351416
});
352417
}
353418
}
@@ -393,6 +458,28 @@ impl ModJson {
393458
));
394459
}
395460

461+
let v5: bool = {
462+
let geode = Version::parse(self.geode.trim_start_matches('v'))
463+
.map_err(|_| ModZipError::InvalidModJson("Invalid geode version".into()))?;
464+
geode.major >= 5
465+
};
466+
467+
// Don't allow array syntax for geode >= v5
468+
if let Some(ModJsonDependencies::Old(_)) = &self.dependencies
469+
&& v5
470+
{
471+
return Err(ModZipError::InvalidModJson(
472+
"Invalid dependencies key: should be an object".into(),
473+
));
474+
}
475+
if let Some(ModJsonIncompatibilities::Old(_)) = &self.incompatibilities
476+
&& v5
477+
{
478+
return Err(ModZipError::InvalidModJson(
479+
"Invalid incompatibilities key: should be an object".into(),
480+
));
481+
}
482+
396483
if let Some(l) = &self.links {
397484
if let Some(community) = &l.community {
398485
if let Err(e) = Url::parse(community) {

src/types/models/dependency.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub struct ResponseDependency {
2121
pub mod_id: String,
2222
pub version: String,
2323
pub importance: DependencyImportance,
24+
pub required: bool,
2425
}
2526

2627
#[derive(sqlx::FromRow, Clone, Debug)]
@@ -44,6 +45,7 @@ impl FetchedDependency {
4445
}
4546
},
4647
importance: self.importance,
48+
required: self.importance == DependencyImportance::Required
4749
}
4850
}
4951
pub fn to_response(&self) -> ResponseDependency {
@@ -57,6 +59,7 @@ impl FetchedDependency {
5759
}
5860
},
5961
importance: self.importance,
62+
required: self.importance == DependencyImportance::Required
6063
}
6164
}
6265
}
@@ -93,7 +96,7 @@ impl Display for ModVersionCompare {
9396
}
9497
}
9598

96-
#[derive(sqlx::Type, Debug, Deserialize, Serialize, Clone, Copy, Default)]
99+
#[derive(sqlx::Type, Debug, Deserialize, Serialize, Clone, Copy, Default, PartialEq)]
97100
#[sqlx(type_name = "dependency_importance", rename_all = "lowercase")]
98101
#[serde(rename_all = "lowercase")]
99102
pub enum DependencyImportance {

src/types/models/incompatibility.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ pub struct ResponseIncompatibility {
5454
pub mod_id: String,
5555
pub version: String,
5656
pub importance: IncompatibilityImportance,
57+
pub breaking: bool,
5758
}
5859

5960
impl FetchedIncompatibility {
@@ -68,6 +69,7 @@ impl FetchedIncompatibility {
6869
}
6970
},
7071
importance: self.importance,
72+
breaking: self.importance == IncompatibilityImportance::Breaking,
7173
}
7274
}
7375

@@ -82,6 +84,7 @@ impl FetchedIncompatibility {
8284
}
8385
},
8486
importance: self.importance,
87+
breaking: self.importance == IncompatibilityImportance::Breaking,
8588
}
8689
}
8790
}

0 commit comments

Comments
 (0)