Skip to main content

brep_kernel/feature_pipeline/
schema.rs

1//! The feature-schema catalogue — kernel-owned feature DEFINITIONS.
2//!
3//! Each feature's schema lives WITH its own code (`features/<feat>.rs` exposes
4//! `schema()` — name, display-builder flag, `inputParamsSchema` — exactly the
5//! shape the caller's feature classes declared). This module only AGGREGATES them, in
6//! the registry's presentation order, and serves the catalogue to the caller's feature editor
7//! via [`feature_schemas_json`]. The caller's feature registry initializes from this;
8//! there is no caller-side schema. Function-valued UI fields (button actions,
9//! custom widgets) cannot cross the JSON boundary — the caller's hook code merges
10//! those back per-param at registry init.
11
12use wasm_bindgen::prelude::*;
13
14/// Assemble the catalogue from every feature's own `schema()`. The assembly
15/// constraint schemas (build-spec §4) join the export under their own
16/// `assemblyConstraints` namespace so the dialog engine renders them with the
17/// same machinery.
18pub fn feature_schema_catalogue() -> serde_json::Value {
19    serde_json::json!({
20        "version": 1,
21        "assemblyConstraints": super::assembly::constraint_schema_catalogue(),
22        "features": [
23            super::features::datum::schema(),
24            super::features::plane::schema(),
25            super::features::cube::schema(),
26            super::features::cylinder::schema(),
27            super::features::cone::schema(),
28            super::features::sphere::schema(),
29            super::features::torus::schema(),
30            super::features::pyramid::schema(),
31            super::features::import3d::schema(),
32            super::features::sketch::schema(),
33            super::features::spline::schema(),
34            super::features::port::schema(),
35            super::features::helix::schema(),
36            super::features::extrude::schema(),
37            super::features::boolean::schema(),
38            super::features::fillet::schema(),
39            super::features::chamfer::schema(),
40            super::features::offset_shell::schema(),
41            super::features::offset_face::schema(),
42            super::features::push_face::schema(),
43            super::features::delete_face::schema(),
44            super::features::thicken::schema(),
45            super::features::sheet_metal_tab::schema(),
46            super::features::sheet_metal_contour_flange::schema(),
47            super::features::sheet_metal_flange::schema(),
48            super::features::sheet_metal_hem::schema(),
49            super::features::sheet_metal_corner::schema_fillet(),
50            super::features::sheet_metal_corner::schema_chamfer(),
51            super::features::sheet_metal_cutout::schema(),
52            super::features::loft::schema(),
53            super::features::mirror::schema(),
54            super::features::split::schema(),
55            super::features::revolve::schema(),
56            super::features::rib::schema(),
57            super::features::sweep::schema(),
58            super::features::path_sweep::schema(),
59            super::features::hole::schema(),
60            super::features::tube::schema(),
61            super::features::transform::schema(),
62            super::features::pattern::schema(),
63            super::features::assembly_component::schema()
64        ]
65    })
66}
67
68/// wasm boundary: the whole feature-schema catalogue as JSON.
69#[wasm_bindgen]
70pub fn feature_schemas_json() -> String {
71    feature_schema_catalogue().to_string()
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77
78    /// The catalogue assembles, covers every dispatchable feature type, and every
79    /// entry has the fields the caller's registry shell requires.
80    #[test]
81    fn schema_catalogue_is_valid_and_complete() {
82        let parsed = feature_schema_catalogue();
83        let features = parsed["features"].as_array().expect("features array");
84        assert!(features.len() >= 30, "catalogue unexpectedly small");
85
86        let mut types = std::collections::HashSet::new();
87        for feature in features {
88            let short = feature["shortName"].as_str().expect("shortName");
89            assert!(!short.is_empty());
90            assert!(feature["longName"].as_str().is_some(), "{short}: longName");
91            assert!(
92                feature["inputParamsSchema"].is_object(),
93                "{short}: inputParamsSchema object"
94            );
95            assert!(
96                feature["displayBuilder"].is_boolean(),
97                "{short}: displayBuilder flag"
98            );
99            types.insert(short.to_string());
100        }
101        for required in [
102            "D", "P", "S", "SP", "PORT", "HX", "P.CU", "P.S", "P.CY", "P.CO", "P.T", "P.PY", "E",
103            "R", "LOFT", "SW", "SWP", "RIB", "TU", "B", "M", "SPL", "XFORM", "PATTERN", "F", "CH",
104            "O.S", "O.F", "PF", "DF", "THK", "H", "IMPORT3D", "SM.TAB", "SM.CF", "SM.F", "SM.HEM",
105            "SM.CFIL", "SM.CCHM", "SM.CUTOUT", "ACOMP",
106        ] {
107            assert!(types.contains(required), "schema catalogue missing {required}");
108        }
109    }
110}