1use indexmap::IndexMap;
2use serde::{Deserialize, Serialize};
3use opys_mojang_rules::{OsOptions, RuleError};
4
5use crate::shorthand::ShorthandError;
6use crate::val::{encode_valset, parse_valset, resolve_valset, ValWire, Valset};
7use crate::valdefs::{
8 encode_val_defs, parse_val_defs, resolve_val_defs, ValDefWire, ValDefs,
9};
10
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct Launch {
13 pub command: String,
14 pub workdir: String,
15 pub args: Valset,
16 pub envs: ValDefs,
17}
18
19#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct LaunchWire {
21 pub command: String,
22 pub workdir: String,
23 #[serde(default, skip_serializing_if = "Option::is_none")]
24 pub args: Option<Vec<ValWire>>,
25 #[serde(default, skip_serializing_if = "Option::is_none")]
26 pub envs: Option<IndexMap<String, ValDefWire>>,
27}
28
29pub fn decode_launch(raw: LaunchWire) -> Result<Launch, ShorthandError> {
30 Ok(Launch {
31 command: raw.command,
32 workdir: raw.workdir,
33 args: raw.args.map(parse_valset).transpose()?.unwrap_or_default(),
34 envs: raw.envs.map(parse_val_defs).transpose()?.unwrap_or_default(),
35 })
36}
37
38pub fn encode_launch(launch: &Launch) -> serde_json::Value {
39 let mut m = serde_json::Map::new();
40 m.insert("command".into(), serde_json::Value::String(launch.command.clone()));
41 m.insert("workdir".into(), serde_json::Value::String(launch.workdir.clone()));
42 m.insert(
43 "args".into(),
44 serde_json::Value::Array(encode_valset(&launch.args)),
45 );
46 m.insert("envs".into(), encode_val_defs(&launch.envs));
47 serde_json::Value::Object(m)
48}
49
50pub fn resolved_args(
51 launch: &Launch,
52 os: &OsOptions,
53 feats: &[String],
54) -> Result<Vec<String>, RuleError> {
55 resolve_valset(&launch.args, os, feats)
56}
57
58pub fn resolved_envs(
59 launch: &Launch,
60 os: &OsOptions,
61 feats: &[String],
62) -> Result<IndexMap<String, String>, RuleError> {
63 resolve_val_defs(&launch.envs, os, feats)
64}