Skip to content

Commit 6f81a64

Browse files
committed
Merge remote-tracking branch 'refs/remotes/origin/main'
2 parents 26452e3 + d6cbc52 commit 6f81a64

File tree

3 files changed

+102
-20
lines changed

3 files changed

+102
-20
lines changed

src/index.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,9 +349,9 @@ pub fn subcommand(cmd: Index) {
349349
let config = &mut _config;
350350
match cmd {
351351
Index::Install { id, version } => {
352-
let mut config = Config::new().assert_is_setup();
352+
let config = Config::new().assert_is_setup();
353353
install_mod(
354-
&mut config,
354+
&config,
355355
&id,
356356
&version.unwrap_or(VersionReq::STAR),
357357
false,

src/project.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ pub fn check_dependencies(
305305
});
306306

307307
// check all dependencies
308-
for dep in mod_info.dependencies {
308+
for dep in &mod_info.dependencies {
309309
// Skip dependencies not on this platform
310310
if !dep.platforms.contains(&platform) {
311311
continue;
@@ -349,7 +349,7 @@ pub fn check_dependencies(
349349
// otherwise try to find it on installed mods and then on index
350350

351351
// check index
352-
let found_in_index = match find_index_dependency(&dep, &config) {
352+
let found_in_index = match find_index_dependency(dep, &config) {
353353
Ok(f) => f,
354354
Err(e) => {
355355
warn!("Failed to fetch dependency {} from index: {}", &dep.id, e);
@@ -358,16 +358,14 @@ pub fn check_dependencies(
358358
};
359359
// check installed mods
360360
let found_in_installed =
361-
find_dependency(&dep, &config.get_current_profile().mods_dir(), true, false)
361+
find_dependency(dep, &config.get_current_profile().mods_dir(), true, false)
362362
.nice_unwrap("Unable to read installed mods");
363363

364364
// if not found in either hjfod code
365365
if !matches!(found_in_index, Found::Some(_, _))
366366
&& !matches!(found_in_installed, Found::Some(_, _))
367367
{
368-
if dep.importance == DependencyImportance::Required
369-
|| dep.required.is_some() && dep.required.unwrap()
370-
{
368+
if dep.importance == DependencyImportance::Required {
371369
fail!(
372370
"Dependency '{0}' not found in installed mods nor index! \
373371
If this is a mod that hasn't been published yet, install it \
@@ -515,12 +513,10 @@ pub fn check_dependencies(
515513
// add a note saying if the dependencey is required or not (for cmake to
516514
// know if to link or not)
517515
fs::write(
518-
dep_dir.join(dep.id).join("geode-dep-options.json"),
516+
dep_dir.join(&dep.id).join("geode-dep-options.json"),
519517
format!(
520518
r#"{{ "required": {} }}"#,
521-
if dep.importance == DependencyImportance::Required
522-
|| dep.required.is_some() && dep.required.unwrap()
523-
{
519+
if dep.importance == DependencyImportance::Required {
524520
"true"
525521
} else {
526522
"false"
@@ -552,7 +548,7 @@ fn add_resource(dir: &Path, resource: ResourceType, files: Vec<PathBuf>) {
552548
let mut new_resource: Vec<Value> = resource.into_iter().chain(files.clone().into_iter().filter_map(|x| {
553549
if !x.exists() {
554550
warn!("{} {} does not exist", othername, x.display());
555-
return None
551+
None
556552
} else {
557553
Some(Value::String(x.as_os_str().to_str().unwrap().to_string()))
558554
}
@@ -584,7 +580,7 @@ fn add_resource(dir: &Path, resource: ResourceType, files: Vec<PathBuf>) {
584580
let mut new_fonts: Vec<Value> = fonts.into_iter().chain(files.into_iter().filter_map(|x| {
585581
if !x.exists() {
586582
warn!("Font {} does not exist", x.display());
587-
return None
583+
None
588584
} else {
589585
Some(json!({
590586
"path": x.as_os_str().to_str().unwrap().to_string(),

src/util/mod_file.rs

Lines changed: 92 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::spritesheet::SpriteSheet;
22
use crate::NiceUnwrap;
33
use clap::ValueEnum;
44
use semver::{Version, VersionReq};
5-
use serde::{Deserialize, Deserializer};
5+
use serde::{Deserialize, Deserializer, de::Error};
66
use std::collections::{HashMap, HashSet};
77
use std::fmt::Display;
88
use std::fs;
@@ -122,7 +122,7 @@ where
122122
Ok(<HashMap<String, BitmapFont>>::deserialize(deserializer)?
123123
.into_iter()
124124
.map(|(name, mut font)| {
125-
font.name = name.clone();
125+
font.name.clone_from(&name);
126126
font.path = std::env::current_dir().unwrap().join(font.path);
127127
(name, font)
128128
})
@@ -286,18 +286,104 @@ pub enum DependencyImportance {
286286
Suggested,
287287
}
288288

289-
#[derive(Default, Deserialize, PartialEq)]
289+
#[derive(Deserialize, PartialEq)]
290290
pub struct Dependency {
291+
#[serde(skip)]
291292
pub id: String,
292293
#[serde(deserialize_with = "parse_comparable_version")]
293294
pub version: VersionReq,
294295
#[serde(default)]
295296
pub importance: DependencyImportance,
296-
pub required: Option<bool>,
297297
#[serde(default = "all_platforms")]
298298
pub platforms: HashSet<PlatformName>,
299299
}
300300

301+
#[derive(Deserialize, PartialEq)]
302+
pub struct LegacyDependency {
303+
pub id: String,
304+
#[serde(deserialize_with = "parse_comparable_version")]
305+
pub version: VersionReq,
306+
#[serde(default)]
307+
pub importance: DependencyImportance,
308+
#[serde(default = "all_platforms")]
309+
pub platforms: HashSet<PlatformName>,
310+
}
311+
312+
#[derive(PartialEq)]
313+
pub struct Dependencies(HashMap<String, Dependency>);
314+
315+
impl Dependencies {
316+
pub fn is_empty(&self) -> bool {
317+
self.0.is_empty()
318+
}
319+
}
320+
321+
impl<'a> IntoIterator for &'a Dependencies {
322+
type IntoIter = std::collections::hash_map::Values<'a, String, Dependency>;
323+
type Item = &'a Dependency;
324+
fn into_iter(self) -> Self::IntoIter {
325+
self.0.values()
326+
}
327+
}
328+
329+
// No it can't clippy Dependency doesn't impl Default
330+
#[allow(clippy::derivable_impls)]
331+
impl Default for Dependencies {
332+
fn default() -> Self {
333+
Self(HashMap::new())
334+
}
335+
}
336+
337+
fn parse_dependencies<'de, D>(deserializer: D) -> Result<Dependencies, D::Error>
338+
where
339+
D: Deserializer<'de>,
340+
{
341+
// This is all to avoid union types having terrible errors
342+
// (they just log "failed to parse any variant of X")
343+
344+
// This is needed because deserializer is moved
345+
let value = serde_json::Value::deserialize(deserializer)?;
346+
347+
match <HashMap<String, serde_json::Value>>::deserialize(value.clone()) {
348+
Ok(deps) => Ok(Dependencies(
349+
deps.into_iter().map(|(id, json)| {
350+
// Shorthand is just "[mod.id]": "[version]"
351+
match parse_comparable_version(json.clone()) {
352+
Ok(version) => Ok(Dependency {
353+
id: id.clone(),
354+
version,
355+
importance: DependencyImportance::Required,
356+
platforms: all_platforms(),
357+
}),
358+
// Longhand is "[mod.id]": { ... }
359+
Err(_) => Dependency::deserialize(json)
360+
// The ID isn't parsed from the object itself but is the key
361+
.map(|mut d| { d.id.clone_from(&id); d })
362+
.map_err(D::Error::custom)
363+
}.map(|r| (id, r))
364+
}).collect::<Result<_, _>>()?
365+
)),
366+
Err(e) => {
367+
// Can be removed after Geode hits v5
368+
match <Vec<LegacyDependency>>::deserialize(value) {
369+
Ok(deps) => {
370+
let mut res = Dependencies::default();
371+
for dep in deps {
372+
res.0.insert(dep.id.clone(), Dependency {
373+
id: dep.id,
374+
version: dep.version,
375+
importance: dep.importance,
376+
platforms: dep.platforms
377+
});
378+
}
379+
Ok(res)
380+
}
381+
Err(_) => Err(D::Error::custom(e))
382+
}
383+
}
384+
}
385+
}
386+
301387
#[derive(Default, Deserialize, PartialEq)]
302388
pub struct ModApi {
303389
#[serde(deserialize_with = "parse_glob_rel")]
@@ -347,8 +433,8 @@ pub struct ModFileInfo {
347433
pub description: String,
348434
#[serde(default)]
349435
pub resources: ModResources,
350-
#[serde(default)]
351-
pub dependencies: Vec<Dependency>,
436+
#[serde(default, deserialize_with = "parse_dependencies")]
437+
pub dependencies: Dependencies,
352438
pub api: Option<ModApi>,
353439
}
354440

0 commit comments

Comments
 (0)