Skip to main content

opys_core/
val.rs

1use serde::{Deserialize, Serialize};
2use opys_mojang_rules::{satisfies_ruleset, OsOptions, RuleError, Ruleset};
3
4use crate::shorthand::{encode_short_ruleset, parse_short_ruleset, RawRuleset, ShorthandError};
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct Val {
8    pub rules: Ruleset,
9    pub value: Vec<String>,
10}
11
12/// Wire shape: a bare string, or an object with `rules` + `value`.
13#[derive(Debug, Clone, Serialize, Deserialize)]
14#[serde(untagged)]
15pub enum ValWire {
16    Bare(String),
17    Object {
18        #[serde(default, skip_serializing_if = "Option::is_none")]
19        rules: Option<RawRuleset>,
20        value: ValValueWire,
21    },
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize)]
25#[serde(untagged)]
26pub enum ValValueWire {
27    One(String),
28    Many(Vec<String>),
29}
30
31pub fn parse_val(raw: ValWire) -> Result<Val, ShorthandError> {
32    match raw {
33        ValWire::Bare(s) => Ok(Val {
34            rules: Vec::new(),
35            value: vec![s],
36        }),
37        ValWire::Object { rules, value } => Ok(Val {
38            rules: match rules {
39                Some(r) => parse_short_ruleset(r)?,
40                None => Vec::new(),
41            },
42            value: match value {
43                ValValueWire::One(s) => vec![s],
44                ValValueWire::Many(v) => v,
45            },
46        }),
47    }
48}
49
50pub fn encode_val(val: &Val) -> serde_json::Value {
51    if val.rules.is_empty() && val.value.len() == 1 {
52        return serde_json::Value::String(val.value[0].clone());
53    }
54    let mut map = serde_json::Map::new();
55    map.insert(
56        "rules".into(),
57        serde_json::to_value(encode_short_ruleset(&val.rules)).unwrap(),
58    );
59    map.insert(
60        "value".into(),
61        serde_json::Value::Array(
62            val.value
63                .iter()
64                .cloned()
65                .map(serde_json::Value::String)
66                .collect(),
67        ),
68    );
69    serde_json::Value::Object(map)
70}
71
72pub type Valset = Vec<Val>;
73
74pub fn parse_valset(raw: Vec<ValWire>) -> Result<Valset, ShorthandError> {
75    raw.into_iter().map(parse_val).collect()
76}
77
78pub fn encode_valset(vs: &Valset) -> Vec<serde_json::Value> {
79    vs.iter().map(encode_val).collect()
80}
81
82pub fn resolve_valset(
83    vs: &Valset,
84    os: &OsOptions,
85    feats: &[String],
86) -> Result<Vec<String>, RuleError> {
87    let mut acc = Vec::new();
88    for val in vs {
89        if satisfies_ruleset(&val.rules, os, feats)? {
90            acc.extend_from_slice(&val.value);
91        }
92    }
93    Ok(acc)
94}