Skip to content

Commit 4471cfb

Browse files
TheCandianVendingMachineBrettMaysonCopilot
authored
config: add flag to output derap'd configs as json (#1021)
* Change config visibility * add json formatting of configs * clippy suggestions * change to feature flag locked derive * change feature flag to be less overarching * add custom serialization of fields * format * Apply suggestions from code review Co-authored-by: Copilot <[email protected]> * fmt, fix copilot being wrong * add __parent * and fmt --------- Co-authored-by: BrettMayson <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent 75dfa26 commit 4471cfb

File tree

13 files changed

+182
-7
lines changed

13 files changed

+182
-7
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bin/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ bench = false
2121
[dependencies]
2222
hemtt-common = { path = "../libs/common" }
2323

24-
hemtt-config = { path = "../libs/config" }
24+
hemtt-config = { path = "../libs/config", features=["serde"] }
2525
hemtt-p3d = { path = "../libs/p3d" }
2626
hemtt-paa = { path = "../libs/paa" }
2727
hemtt-pbo = { path = "../libs/pbo" }

bin/src/utils/config/derapify.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,60 @@
1+
use serde_json;
12
use std::{io::Write as _, path::PathBuf};
23

34
use hemtt_config::rapify::Derapify;
45

56
use crate::Error;
67

8+
#[derive(Debug, Copy, Clone, clap::ValueEnum)]
9+
pub enum OutputFormat {
10+
Debin,
11+
Json,
12+
JsonPretty,
13+
}
14+
15+
impl OutputFormat {
16+
fn default_extension(&self) -> &str {
17+
match self {
18+
Self::Debin => "cpp",
19+
Self::JsonPretty | Self::Json => "json",
20+
}
21+
}
22+
}
23+
724
#[derive(clap::Args)]
825
#[allow(clippy::module_name_repetitions)]
926
pub struct DerapifyArgs {
1027
/// file to derapify
1128
pub(crate) file: String,
29+
/// output format
30+
#[arg(short = 'f', long = "format", default_value = "debin")]
31+
pub(crate) output_format: OutputFormat,
1232
/// output file
1333
pub(crate) output: Option<String>,
1434
}
1535

1636
/// Derapify a config file
17-
pub fn derapify(path: &PathBuf, output: Option<&str>) -> Result<(), Error> {
37+
pub fn derapify(path: &PathBuf, output: Option<&str>, format: OutputFormat) -> Result<(), Error> {
1838
let mut file = std::fs::File::open(path)?;
1939
let config = hemtt_config::Config::derapify(&mut file)?;
2040
let output = output.map_or_else(
2141
|| {
2242
let mut path = path.clone();
23-
path.set_extension("cpp");
43+
path.set_extension(format.default_extension());
2444
path
2545
},
2646
PathBuf::from,
2747
);
2848
let mut output = std::fs::File::create(output)?;
29-
output.write_all(config.to_string().as_bytes())?;
49+
match format {
50+
OutputFormat::Debin => output.write_all(config.to_string().as_bytes())?,
51+
OutputFormat::Json => {
52+
output.write_all(serde_json::to_string(&config)?.as_bytes())?;
53+
}
54+
OutputFormat::JsonPretty => {
55+
output.write_all(serde_json::to_string_pretty(&config)?.as_bytes())?;
56+
}
57+
}
3058
output.flush()?;
3159
Ok(())
3260
}

bin/src/utils/config/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@ enum Subcommands {
3232
/// If the args are not present from clap
3333
pub fn execute(cmd: &Command) -> Result<(), Error> {
3434
match &cmd.commands {
35-
Subcommands::Derapify(args) => {
36-
derapify::derapify(&PathBuf::from(&args.file), args.output.as_deref())
37-
}
35+
Subcommands::Derapify(args) => derapify::derapify(
36+
&PathBuf::from(&args.file),
37+
args.output.as_deref(),
38+
args.output_format,
39+
),
3840
Subcommands::Inspect(args) => inspect::inspect(&PathBuf::from(&args.config)),
3941
}
4042
}

libs/config/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ lsp-types = { workspace = true }
2525
toml = { workspace = true }
2626
vfs = { workspace = true }
2727

28+
serde = { version = "1.0.219", features = ["derive"], optional = true }
29+
2830
[dev-dependencies]
2931
hemtt-preprocessor = { path = "../preprocessor" }
3032
insta = { workspace = true }
3133
paste = { workspace = true }
34+

libs/config/src/model/array.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,40 @@ pub enum Item {
2222
/// An invalid value
2323
Invalid(Range<usize>),
2424
}
25+
26+
#[cfg(feature = "serde")]
27+
impl serde::Serialize for Array {
28+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
29+
where
30+
S: serde::Serializer,
31+
{
32+
use serde::ser::SerializeSeq;
33+
let mut state = serializer.serialize_seq(Some(self.items.len()))?;
34+
for item in &self.items {
35+
state.serialize_element(&item)?;
36+
}
37+
state.end()
38+
}
39+
}
40+
41+
#[cfg(feature = "serde")]
42+
impl serde::Serialize for Item {
43+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
44+
where
45+
S: serde::Serializer,
46+
{
47+
match self {
48+
Self::Str(str) => str.serialize(serializer),
49+
Self::Number(number) => number.serialize(serializer),
50+
Self::Array(items) => {
51+
use serde::ser::SerializeSeq;
52+
let mut state = serializer.serialize_seq(Some(items.len()))?;
53+
for item in items {
54+
state.serialize_element(item)?;
55+
}
56+
state.end()
57+
}
58+
Self::Invalid(_) => serializer.serialize_none(),
59+
}
60+
}
61+
}

libs/config/src/model/class.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,33 @@ impl Class {
7474
}
7575
}
7676
}
77+
78+
#[cfg(feature = "serde")]
79+
impl serde::Serialize for Class {
80+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
81+
where
82+
S: serde::Serializer,
83+
{
84+
match self {
85+
Self::Local { properties, .. } | Self::Root { properties } => {
86+
use serde::ser::SerializeMap;
87+
let mut state = serializer.serialize_map(Some(properties.len()))?;
88+
if let Self::Local { parent, .. } = self
89+
&& let Some(parent) = parent
90+
{
91+
state.serialize_entry("__parent", parent.as_str())?;
92+
}
93+
for property in properties {
94+
state.serialize_entry(property.name().as_str(), property)?;
95+
}
96+
state.end()
97+
}
98+
Self::External { name } => {
99+
use serde::ser::SerializeMap;
100+
let mut state = serializer.serialize_map(Some(1))?;
101+
state.serialize_entry(name.as_str(), &{})?;
102+
state.end()
103+
}
104+
}
105+
}
106+
}

libs/config/src/model/config.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,13 @@ impl Config {
5151
patches
5252
}
5353
}
54+
55+
#[cfg(feature = "serde")]
56+
impl serde::Serialize for Config {
57+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
58+
where
59+
S: serde::Serializer,
60+
{
61+
self.to_class().serialize(serializer)
62+
}
63+
}

libs/config/src/model/expression.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,13 @@ pub struct Expression {
66
pub(crate) value: String,
77
pub(crate) span: Range<usize>,
88
}
9+
10+
#[cfg(feature = "serde")]
11+
impl serde::Serialize for Expression {
12+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
13+
where
14+
S: serde::Serializer,
15+
{
16+
serializer.serialize_str(&self.value)
17+
}
18+
}

libs/config/src/model/number.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,17 @@ impl Number {
7979
}
8080
}
8181
}
82+
83+
#[cfg(feature = "serde")]
84+
impl serde::Serialize for Number {
85+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
86+
where
87+
S: serde::Serializer,
88+
{
89+
match self {
90+
Self::Int32 { value, .. } => serializer.serialize_i32(*value),
91+
Self::Int64 { value, .. } => serializer.serialize_i64(*value),
92+
Self::Float32 { value, .. } => serializer.serialize_f32(*value),
93+
}
94+
}
95+
}

0 commit comments

Comments
 (0)