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