Skip to content

Commit d0c92db

Browse files
committed
feat: add more stuff to mod project config
1 parent 76afc18 commit d0c92db

File tree

5 files changed

+179
-26
lines changed

5 files changed

+179
-26
lines changed

crates/mod-project/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ edition = "2021"
66
[dependencies]
77
serde = { version = "1.0", features = ["derive"] }
88
toml = "0.8.19"
9+
serde_json = "1.0"

crates/mod-project/src/lib.rs

Lines changed: 133 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,157 @@
11
use serde::{Deserialize, Serialize};
2+
use std::collections::HashMap;
23

3-
#[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd)]
4+
/// Describes a mod project configuration file
5+
#[derive(Serialize, Deserialize, Debug, PartialEq)]
46
pub struct ModProject {
7+
/// The name of the mod
8+
/// Must not contain spaces or special characters except for underscores and hyphens
9+
///
10+
/// Example: `my_mod`
511
pub name: String,
12+
13+
/// The display name of the mod.
14+
///
15+
/// Example: `My Mod`
616
pub display_name: String,
17+
18+
/// The version of the mod
19+
///
20+
/// Example: `1.0.0`
721
pub version: String,
22+
23+
/// The description of the mod
24+
///
25+
/// Example: `This is a mod for my game`
826
pub description: String,
27+
28+
/// The authors of the mod
929
pub authors: Vec<ModProjectAuthor>,
30+
31+
/// File transformers to be applied during the build process
32+
/// Optional field - if not provided, no transformers will be applied
33+
#[serde(default, skip_serializing_if = "Vec::is_empty")]
34+
pub transformers: Vec<FileTransformer>,
35+
36+
/// Layers of the mod project
37+
/// Layers are loaded in order of priority (highest priority last)
38+
/// If not specified, a default "base" layer with priority 0 is assumed
39+
#[serde(default = "default_layers")]
40+
pub layers: Vec<ModLayer>,
41+
}
42+
43+
/// Returns the default layers for a mod project
44+
fn default_layers() -> Vec<ModLayer> {
45+
vec![ModLayer {
46+
name: "base".to_string(),
47+
priority: 0,
48+
description: Some("Base layer of the mod".to_string()),
49+
}]
1050
}
1151

12-
#[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd)]
52+
/// Represents a layer in a mod project
53+
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
54+
pub struct ModLayer {
55+
/// The name of the layer
56+
/// Must not contain spaces or special characters except for underscores and hyphens
57+
///
58+
/// Example: `base`, `high_res_textures`, `gameplay_overhaul`
59+
pub name: String,
60+
61+
/// The priority of the layer
62+
/// Higher priority layers override lower priority layers when they modify the same files
63+
/// Default is 0 for the base layer
64+
pub priority: i32,
65+
66+
/// Optional description of the layer
67+
#[serde(default, skip_serializing_if = "Option::is_none")]
68+
pub description: Option<String>,
69+
}
70+
71+
#[derive(Serialize, Deserialize, Debug, PartialEq)]
1372
#[serde(untagged)]
1473
pub enum ModProjectAuthor {
1574
Name(String),
1675
Role { name: String, role: String },
1776
}
1877

78+
/// Represents a file transformer that can be applied to files during the build process
79+
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
80+
pub struct FileTransformer {
81+
/// The name of the transformer to use.
82+
pub name: String,
83+
84+
/// File patterns to apply this transformer to.
85+
/// At least one of `patterns` or `files` must be provided
86+
#[serde(default, skip_serializing_if = "Vec::is_empty")]
87+
pub patterns: Vec<String>,
88+
89+
/// Specific files to apply this transformer to.
90+
/// At least one of `patterns` or `files` must be provided
91+
#[serde(default, skip_serializing_if = "Vec::is_empty")]
92+
pub files: Vec<String>,
93+
94+
/// Transformer-specific configuration
95+
/// This is an optional field that can be used to configure the transformer
96+
#[serde(default, skip_serializing_if = "Option::is_none")]
97+
pub options: Option<FileTransformerOptions>,
98+
}
99+
100+
pub type FileTransformerOptions = HashMap<String, serde_json::Value>;
101+
19102
#[cfg(test)]
20103
mod tests {
21104
use super::*;
22105

106+
fn create_example_project() -> ModProject {
107+
ModProject {
108+
name: "old-summoners-rift".to_string(),
109+
display_name: "Old Summoners Rift".to_string(),
110+
version: "0.1.0-beta.5".to_string(),
111+
description:
112+
"A mod for League of Legends that changes the map to the old Summoners Rift"
113+
.to_string(),
114+
authors: vec![
115+
ModProjectAuthor::Name("TheKillerey".to_string()),
116+
ModProjectAuthor::Role {
117+
name: "Crauzer".to_string(),
118+
role: "Contributor".to_string(),
119+
},
120+
],
121+
transformers: vec![FileTransformer {
122+
name: "tex-converter".to_string(),
123+
patterns: vec!["**/*.dds".to_string(), "**/*.png".to_string()],
124+
files: vec![],
125+
options: None,
126+
}],
127+
layers: vec![
128+
ModLayer {
129+
name: "base".to_string(),
130+
priority: 0,
131+
description: Some("Base layer of the mod".to_string()),
132+
},
133+
ModLayer {
134+
name: "chroma1".to_string(),
135+
priority: 20,
136+
description: Some("Chroma 1".to_string()),
137+
},
138+
],
139+
}
140+
}
141+
23142
#[test]
24-
fn example_project() {
143+
fn test_json_parsing() {
25144
let project: ModProject =
26-
toml::from_str(include_str!("../test-data/modproject.toml")).unwrap();
27-
28-
assert_eq!(
29-
project,
30-
ModProject {
31-
name: "test".to_string(),
32-
display_name: "Test 123".to_string(),
33-
version: "0.1.0".to_string(),
34-
description: "test".to_string(),
35-
authors: vec![
36-
ModProjectAuthor::Name("test".to_string()),
37-
ModProjectAuthor::Role {
38-
name: "test 2".to_string(),
39-
role: "developer".to_string(),
40-
},
41-
],
42-
}
43-
);
145+
serde_json::from_str(include_str!("../test-data/mod.config.json")).unwrap();
146+
147+
assert_eq!(project, create_example_project());
148+
}
149+
150+
#[test]
151+
fn test_toml_parsing() {
152+
let project: ModProject =
153+
toml::from_str(include_str!("../test-data/mod.config.toml")).unwrap();
154+
155+
assert_eq!(project, create_example_project());
44156
}
45157
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "old-summoners-rift",
3+
"display_name": "Old Summoners Rift",
4+
"version": "0.1.0-beta.5",
5+
"description": "A mod for League of Legends that changes the map to the old Summoners Rift",
6+
"authors": ["TheKillerey", { "name": "Crauzer", "role": "Contributor" }],
7+
"transformers": [
8+
{
9+
"name": "tex-converter",
10+
"patterns": ["**/*.dds", "**/*.png"]
11+
}
12+
],
13+
"layers": [
14+
{
15+
"name": "base",
16+
"priority": 0,
17+
"description": "Base layer of the mod"
18+
},
19+
{
20+
"name": "chroma1",
21+
"priority": 20,
22+
"description": "Chroma 1"
23+
}
24+
]
25+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name = "old-summoners-rift"
2+
display_name = "Old Summoners Rift"
3+
version = "0.1.0-beta.5"
4+
description = "A mod for League of Legends that changes the map to the old Summoners Rift"
5+
6+
authors = ["TheKillerey", { name = "Crauzer", role = "Contributor" }]
7+
8+
[[transformers]]
9+
name = "tex-converter"
10+
patterns = ["**/*.dds", "**/*.png"]
11+
12+
[[layers]]
13+
name = "base"
14+
priority = 0
15+
description = "Base layer of the mod"
16+
17+
[[layers]]
18+
name = "chroma1"
19+
priority = 20
20+
description = "Chroma 1"

crates/mod-project/test-data/modproject.toml

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)