Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions crates/workshop-rs-cli/src/census.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ use crate::conformance::{
TestArtifact,
};
use workshop_rs::catalog::{Catalog, CatalogEntry, EnumDomain, Kind, Locale};
use workshop_rs::settings::schema::{
self as settings_schema, SettingDefinition, SettingValueDomain,
};
use workshop_rs::settings::{self as settings_schema, SettingDefinition, SettingValueDomain};
use workshop_rs::{WorkshopError, convert, emitter, parser, roundtrip};

#[derive(Clone, Copy)]
Expand Down
8 changes: 4 additions & 4 deletions crates/workshop-rs/src/actions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
//! The Workshop action domain.
//!
//! Action data is modeled canonically in [`crate::Program`]. Action-specific
//! layout and element-count operations are re-exported here so contributors
//! can start from the domain rather than from an implementation phase.
//! layout and element-count operations live in [`crate::emitter`], the
//! Workshop-operations entry point; this domain module re-exports the model
//! types only.

pub(crate) mod emitter;
mod layout;
pub(crate) mod layout;
pub(crate) mod parser;
pub(crate) mod validate;

pub use crate::analysis::element_count::{
ElementCountError, ElementCountNode, ElementCountReport, ElementNodeKind,
};
pub use crate::program::{Action, ModifyOp};
pub use layout::{ActionLayout, ActionLayoutError, action_width};
6 changes: 3 additions & 3 deletions crates/workshop-rs/src/bin/workshop-catalog-gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use std::path::{Path, PathBuf};
use std::process::ExitCode;

use workshop_rs::catalog::{Catalog, Locale, build_canonical};
use workshop_rs::settings::schema;
use workshop_rs::settings;

/// The committed catalog data, relative to the workspace root (where CI and
/// the documented pipeline commands run); `--file` overrides it.
Expand Down Expand Up @@ -128,7 +128,7 @@ fn main() -> ExitCode {
}
return ExitCode::from(1);
}
if let Err(errors) = schema::validate_catalog() {
if let Err(errors) = settings::validate_catalog() {
for error in errors {
eprintln!("workshop-catalog-gen: settings catalog: {error}");
}
Expand Down Expand Up @@ -613,7 +613,7 @@ mod corpus {
.collect();
let mut labels: Vec<(String, String)> = Vec::new();
let mut seen = std::collections::HashSet::new();
let definitions: Vec<_> = schema::definitions().collect();
let definitions: Vec<_> = settings::definitions().collect();
for definition in &definitions {
if definition.path().ends_with(".enabled") {
continue;
Expand Down
2 changes: 1 addition & 1 deletion crates/workshop-rs/src/emitter.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Public complete-program Workshop emission over [`crate::Program`].

pub use crate::actions::{ActionLayout, ActionLayoutError, action_width};
pub use crate::actions::layout::{ActionLayout, ActionLayoutError, action_width};
pub use crate::output::emitter::*;

#[cfg(test)]
Expand Down
5 changes: 2 additions & 3 deletions crates/workshop-rs/src/rules/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! The Workshop rule and declaration domain.
//!
//! Rule, variable, and subroutine data is modeled canonically in [`crate::Program`].
//! Whole-program inspection and validation are available from this domain
//! entry point as well as their compatibility modules.
//! Whole-program inspection is available from this domain entry point;
//! canonical validation is at [`crate::validate::validate_canonical_ids`].

pub(crate) mod emitter;
pub(crate) mod parser;
Expand All @@ -12,4 +12,3 @@ pub use crate::analysis::semantic::{
IncompletenessKind, ResidualClassification, SemanticIssue, inspect,
};
pub use crate::program::{Condition, Program, Rule, Subroutine, Variable};
pub use validate::validate_canonical_ids;
4 changes: 2 additions & 2 deletions crates/workshop-rs/src/settings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub(crate) mod emitter;
pub(crate) mod parser;

pub(crate) mod reconciliation;
pub mod schema;
pub(crate) mod schema;
pub(crate) mod table;

/// A segment of a path accepted by settings schema lookups.
Expand Down Expand Up @@ -45,7 +45,7 @@ pub use schema::{
SettingEnumMember, SettingId, SettingIdentity, SettingOccurrence, SettingOperationError,
SettingPresentation, SettingScope, SettingSource, SettingSourceEdit, SettingSourceKind,
SettingTarget, SettingTargetKind, SettingValue, SettingValueDomain, TeamId, definition,
definitions, definitions_by_id,
definitions, definitions_by_id, validate_catalog,
};

use crate::core::source::Span;
Expand Down
9 changes: 4 additions & 5 deletions crates/workshop-rs/tests/action_layout.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use workshop_rs::actions::{self, ActionLayoutError};
use workshop_rs::catalog::{Catalog, Locale};
use workshop_rs::emitter;
use workshop_rs::emitter::{self, ActionLayoutError};
use workshop_rs::{Action, Event, Program, Rule, Value, Variable};

fn program_with_structured_actions() -> (Program, Vec<Action>) {
Expand Down Expand Up @@ -67,7 +66,7 @@ fn structured_action_widths_count_native_expansion() {

for (range, width) in [((0..5), 5), ((5..8), 3), ((8..11), 3), ((11..18), 7)] {
assert_eq!(
actions::action_width(&program, &catalog, &locale, &actions[range])
emitter::action_width(&program, &catalog, &locale, &actions[range])
.unwrap()
.width,
width
Expand All @@ -92,7 +91,7 @@ fn layout_matches_canonical_emission_for_a_nested_sequence() {
.lines()
.filter(|line| !line.trim().is_empty())
.count();
let layout = actions::action_width(&program, &catalog, &locale, &actions).unwrap();
let layout = emitter::action_width(&program, &catalog, &locale, &actions).unwrap();
assert_eq!(layout.width, emitted_width);
assert_eq!(layout.width, 19);
}
Expand All @@ -105,7 +104,7 @@ fn invalid_layout_requests_fail_as_invalid_programs() {
let actions = rule.actions.clone();
program.rules.push(rule);

let error = actions::action_width(
let error = emitter::action_width(
&program,
&Catalog::builtin().unwrap(),
&Locale::new("en-US"),
Expand Down
2 changes: 1 addition & 1 deletion crates/workshop-rs/tests/program_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ fn independently_constructed_program_uses_the_same_operations() {
program.validate().expect("structurally validates");
workshop_rs::validate::validate_canonical_ids(&program, &catalog).expect("catalog validates");
let layout =
workshop_rs::actions::action_width(&program, &catalog, &locale, &program.rules[0].actions)
workshop_rs::emitter::action_width(&program, &catalog, &locale, &program.rules[0].actions)
.expect("lays out");
assert_eq!(layout.width, 1);
let emitted = workshop_rs::emitter::emit(&program, &catalog, &locale).expect("emits");
Expand Down
13 changes: 7 additions & 6 deletions crates/workshop-rs/tests/public_api.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use workshop_rs::catalog::{Catalog, Locale};
use workshop_rs::settings::{PathPart, schema};
use workshop_rs::settings::{self, PathPart};
use workshop_rs::{
Action, Event, MappedText, Program, Rule, SourceMap, Value, emitter, parser, roundtrip, rules,
Action, Event, MappedText, Program, Rule, SourceMap, Value, emitter, parser, roundtrip,
validate,
};

#[test]
Expand All @@ -18,8 +19,8 @@ fn canonical_program_operations_cover_parse_validate_inspect_emit_and_roundtrip(
program
.validate()
.expect("canonical program is structurally valid");
rules::validate_canonical_ids(&program, &catalog)
.expect("canonical ids resolve through the public rule API");
validate::validate_canonical_ids(&program, &catalog)
.expect("canonical ids resolve through the public validate API");
assert!(program.semantic_issues(&catalog).is_empty());

let emitted = emitter::emit(&program, &catalog, &locale).expect("canonical emission");
Expand All @@ -29,7 +30,7 @@ fn canonical_program_operations_cover_parse_validate_inspect_emit_and_roundtrip(

#[test]
fn settings_schema_exposes_enum_values_without_the_internal_table() {
let definition = schema::definition(&[
let definition = settings::definition(&[
PathPart::Part("lobby"),
PathPart::Part("enableMatchVoiceChat"),
])
Expand Down Expand Up @@ -73,7 +74,7 @@ fn catalog_actions_and_values_are_built_by_canonical_id() {
)),
);
program.validate().expect("catalog calls validate");
rules::validate_canonical_ids(&program, &catalog).expect("catalog ids resolve");
validate::validate_canonical_ids(&program, &catalog).expect("catalog ids resolve");

let emitted = emitter::emit(&program, &catalog, &locale).expect("catalog calls emit");
assert!(
Expand Down
5 changes: 4 additions & 1 deletion docs/adr/0006-settings-semantic-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ Query and edit API ergonomics are outside this decision.

## Decision

`workshop-rs` exposes typed setting facts through `settings::schema`.
`workshop-rs` exposes typed setting facts through `settings` (implemented in
the internal `settings::schema` module; see
[`docs/compatibility-facades.md`](../compatibility-facades.md) for the public
path).
`SettingId` is an open, locale-independent identity for a Workshop setting
concept. A concrete hero or ability display label is never required in that
identity; hero and logical ability-slot information is represented by
Expand Down
21 changes: 21 additions & 0 deletions docs/compatibility-facades.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,27 @@ parse-context contract shared by Workshop parsing and frontends that supply
expected enum domains. Both are intentional public APIs, not compatibility-only
facades; the catalog remains the sole source of signature data.

The canonical `Program` model types are also reachable from the domain module
that owns their concept, so contributors and consumers can start from either
the model or the domain: `actions::{Action, ModifyOp}`, `events::{Event,
EventTarget, EventTeam, PlayerEventKind}`, `rules::{Condition, Program, Rule,
Subroutine, Variable}`, and `values::Value` are the same items as their
crate-root and `program::` re-exports, not copies. `program`, the crate root,
and these domain modules are the discoverable Workshop domains described in
the crate's top-level docs; every one of these paths is an intentional public
API and a separate 1.x compatibility commitment.

Every other public item is reachable through exactly one path. `actions`
re-exports the `Program` model types above and its own element-count analysis
types (`ElementCountError`, `ElementCountNode`, `ElementCountReport`,
`ElementNodeKind`); action layout and element-count operations (`ActionLayout`,
`ActionLayoutError`, `action_width`) are public only from `emitter`. `rules`
re-exports the `Program` model types above and its own inspection types
(`IncompletenessKind`, `ResidualClassification`, `SemanticIssue`, `inspect`);
canonical validation (`validate_canonical_ids`) is public only from
`validate`. `settings::schema` is an internal module; its types and functions
(including `validate_catalog`) are public only from `settings` directly.

## Catalog-backed actions and values

Catalog actions and values are built with `Action::call` and `Value::call`,
Expand Down
Loading