Skip to main content

opys_core/
manifest.rs

1use indexmap::IndexMap;
2use serde::{Deserialize, Serialize};
3use opys_mojang_rules::OsOptions;
4
5use crate::artifact::{
6    artifact_applies, decode_artifact, encode_artifact, Artifact, ArtifactWire,
7};
8use crate::launch::{decode_launch, encode_launch, Launch, LaunchWire};
9use crate::shorthand::ShorthandError;
10use crate::valdefs::{encode_val_defs, parse_val_defs, ValDefWire, ValDefs};
11use crate::DecodeError;
12
13#[derive(Debug, Clone, Default, PartialEq, Eq)]
14pub struct Manifest {
15    pub vars: ValDefs,
16    pub launch: Option<Launch>,
17    pub artifacts: Vec<Artifact>,
18    pub restrict: Option<Vec<String>>,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct ManifestWire {
23    #[serde(default, skip_serializing_if = "Option::is_none")]
24    pub vars: Option<IndexMap<String, ValDefWire>>,
25    #[serde(default, skip_serializing_if = "Option::is_none")]
26    pub launch: Option<LaunchWire>,
27    #[serde(default, skip_serializing_if = "Option::is_none")]
28    pub artifacts: Option<Vec<ArtifactWire>>,
29    #[serde(default, skip_serializing_if = "Option::is_none")]
30    pub restrict: Option<Vec<String>>,
31}
32
33pub fn decode_manifest(raw: ManifestWire) -> Result<Manifest, ShorthandError> {
34    Ok(Manifest {
35        vars: raw.vars.map(parse_val_defs).transpose()?.unwrap_or_default(),
36        launch: raw.launch.map(decode_launch).transpose()?,
37        artifacts: raw
38            .artifacts
39            .map(|v| v.into_iter().map(decode_artifact).collect::<Result<_, _>>())
40            .transpose()?
41            .unwrap_or_default(),
42        restrict: raw.restrict,
43    })
44}
45
46pub fn encode_manifest(u: &Manifest) -> serde_json::Value {
47    let mut m = serde_json::Map::new();
48    m.insert("vars".into(), encode_val_defs(&u.vars));
49    if let Some(launch) = &u.launch {
50        m.insert("launch".into(), encode_launch(launch));
51    }
52    m.insert(
53        "artifacts".into(),
54        serde_json::to_value(u.artifacts.iter().map(encode_artifact).collect::<Vec<_>>()).unwrap(),
55    );
56    if let Some(r) = &u.restrict {
57        if !r.is_empty() {
58            m.insert("restrict".into(), serde_json::to_value(r).unwrap());
59        }
60    }
61    serde_json::Value::Object(m)
62}
63
64pub fn parse_manifest(input: &str) -> Result<Manifest, DecodeError> {
65    let wire: ManifestWire = serde_json::from_str(input)
66        .map_err(|e| DecodeError::Manifest(format!("{e}")))?;
67    decode_manifest(wire).map_err(Into::into)
68}
69
70pub fn filter_manifest(
71    u: &Manifest,
72    os: &OsOptions,
73    feats: &[String],
74) -> Result<Manifest, opys_mojang_rules::RuleError> {
75    let artifacts = u
76        .artifacts
77        .iter()
78        .filter_map(|a| match artifact_applies(a, os, feats) {
79            Ok(true) => Some(Ok(a.clone())),
80            Ok(false) => None,
81            Err(e) => Some(Err(e)),
82        })
83        .collect::<Result<_, _>>()?;
84    Ok(Manifest {
85        artifacts,
86        ..u.clone()
87    })
88}