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