Skip to main content

workshop_rs/settings/
mod.rs

1//! The neutral settings carrier.
2//!
3//! A typed, non-serde tree for custom-game-settings blocks shared by
4//! validation and emission. The tree is a carrier: settings are carried and
5//! emitted, never interpreted by lowering/analysis. Source-backed path and
6//! display data remain implementation details behind this module's APIs.
7//!
8//! Extracted from the Wright-authored `wright-ir` crate; see
9//! [`docs/provenance.md`](https://github.com/wrightkit/workshop-rs/blob/main/docs/provenance.md).
10
11pub(crate) mod check;
12pub(crate) mod emitter;
13pub(crate) mod parser;
14
15pub(crate) mod reconciliation;
16pub(crate) mod schema;
17pub(crate) mod table;
18
19/// A segment of a path accepted by settings schema lookups.
20#[derive(Debug, Clone, Copy, Hash)]
21pub enum PathPart<'a> {
22    /// A literal key (mode names under `gamemodes` are literal keys too:
23    /// per-key subsets are exact-path entries).
24    Part(&'a str),
25    /// Any team slot (allTeams).
26    Team,
27    /// Any hero-config slot.
28    Hero,
29}
30
31impl<'b> PartialEq<PathPart<'b>> for PathPart<'_> {
32    fn eq(&self, other: &PathPart<'b>) -> bool {
33        match (self, other) {
34            (PathPart::Part(left), PathPart::Part(right)) => left == right,
35            (PathPart::Team, PathPart::Team) => true,
36            (PathPart::Hero, PathPart::Hero) => true,
37            _ => false,
38        }
39    }
40}
41
42impl Eq for PathPart<'_> {}
43
44pub use check::check_emission;
45pub use schema::{
46    Applicability, EffectiveNumber, NumericBounds, NumericBoundsError, SettingDefinition,
47    SettingEnumMember, SettingId, SettingIdentity, SettingOccurrence, SettingOperationError,
48    SettingPresentation, SettingScope, SettingSource, SettingSourceEdit, SettingSourceKind,
49    SettingTarget, SettingTargetKind, SettingValue, SettingValueDomain, TeamId, definition,
50    definitions, definitions_by_id, validate_catalog,
51};
52
53use crate::core::source::Span;
54
55/// A settings block: `settings { ... }` with its typed children.
56#[derive(Debug, Clone)]
57pub struct Settings {
58    pub span: Option<Span>,
59    pub children: Vec<SettingsNode>,
60}
61
62/// One member of a settings group.
63#[derive(Debug, Clone)]
64pub enum SettingsNode {
65    /// User-authored mode data under `settings.workshop`.
66    Workshop {
67        children: Vec<SettingsNode>,
68        span: Option<Span>,
69    },
70    Group {
71        name: String,
72        children: Vec<SettingsNode>,
73        span: Option<Span>,
74    },
75    Number {
76        name: String,
77        value: f64,
78        span: Option<Span>,
79    },
80    Bool {
81        name: String,
82        value: bool,
83        span: Option<Span>,
84    },
85    /// A presence-only Workshop extension setting (for example `Beam Effects`).
86    Flag { name: String, span: Option<Span> },
87    String {
88        name: String,
89        value: String,
90        span: Option<Span>,
91    },
92    List {
93        name: String,
94        elements: Vec<SettingsListElement>,
95        span: Option<Span>,
96    },
97    /// A syntactically valid settings member whose semantic catalog entry is
98    /// not yet declared. The raw value is carried explicitly so parsing does
99    /// not fabricate a type or silently discard project settings.
100    Raw {
101        name: String,
102        value: String,
103        span: Option<Span>,
104    },
105}
106
107/// One element of a settings list (corpus lists are all strings).
108#[derive(Debug, Clone)]
109pub struct SettingsListElement {
110    pub value: String,
111    pub span: Option<Span>,
112}
113
114impl SettingsNode {
115    /// The source span of this node, if any.
116    pub fn span(&self) -> Option<Span> {
117        match self {
118            SettingsNode::Workshop { span, .. }
119            | SettingsNode::Group { span, .. }
120            | SettingsNode::Number { span, .. }
121            | SettingsNode::Bool { span, .. }
122            | SettingsNode::Flag { span, .. }
123            | SettingsNode::String { span, .. }
124            | SettingsNode::List { span, .. }
125            | SettingsNode::Raw { span, .. } => *span,
126        }
127    }
128
129    /// The key name of this node.
130    pub fn name(&self) -> &str {
131        match self {
132            SettingsNode::Workshop { .. } => "workshop",
133            SettingsNode::Group { name, .. }
134            | SettingsNode::Number { name, .. }
135            | SettingsNode::Bool { name, .. }
136            | SettingsNode::Flag { name, .. }
137            | SettingsNode::String { name, .. }
138            | SettingsNode::List { name, .. }
139            | SettingsNode::Raw { name, .. } => name,
140        }
141    }
142}