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()`.
15pub fn feature_schema_catalogue() -> serde_json::Value {
16    serde_json::json!({
17        "version": 1,
18        "features": [
19            super::features::datum::schema(),
20            super::features::plane::schema(),
21            super::features::cube::schema(),
22            super::features::cylinder::schema(),
23            super::features::cone::schema(),
24            super::features::sphere::schema(),
25            super::features::torus::schema(),
26            super::features::pyramid::schema(),
27            super::features::import3d::schema(),
28            super::features::sketch::schema(),
29            super::features::spline::schema(),
30            super::features::port::schema(),
31            super::features::helix::schema(),
32            super::features::extrude::schema(),
33            super::features::boolean::schema(),
34            super::features::fillet::schema(),
35            super::features::chamfer::schema(),
36            super::features::offset_shell::schema(),
37            super::features::offset_face::schema(),
38            super::features::push_face::schema(),
39            super::features::delete_face::schema(),
40            super::features::thicken::schema(),
41            super::features::sheet_metal_tab::schema(),
42            super::features::sheet_metal_contour_flange::schema(),
43            super::features::sheet_metal_flange::schema(),
44            super::features::sheet_metal_hem::schema(),
45            super::features::sheet_metal_cutout::schema(),
46            super::features::loft::schema(),
47            super::features::mirror::schema(),
48            super::features::split::schema(),
49            super::features::revolve::schema(),
50            super::features::rib::schema(),
51            super::features::sweep::schema(),
52            super::features::path_sweep::schema(),
53            super::features::hole::schema(),
54            super::features::tube::schema(),
55            super::features::transform::schema(),
56            super::features::pattern::schema()
57        ]
58    })
59}
60
61/// wasm boundary: the whole feature-schema catalogue as JSON.
62#[wasm_bindgen]
63pub fn feature_schemas_json() -> String {
64    feature_schema_catalogue().to_string()
65}
66
67#[cfg(test)]
68mod tests {
69    use super::*;
70
71    /// The catalogue assembles, covers every dispatchable feature type, and every
72    /// entry has the fields the caller's registry shell requires.
73    #[test]
74    fn schema_catalogue_is_valid_and_complete() {
75        let parsed = feature_schema_catalogue();
76        let features = parsed["features"].as_array().expect("features array");
77        assert!(features.len() >= 30, "catalogue unexpectedly small");
78
79        let mut types = std::collections::HashSet::new();
80        for feature in features {
81            let short = feature["shortName"].as_str().expect("shortName");
82            assert!(!short.is_empty());
83            assert!(feature["longName"].as_str().is_some(), "{short}: longName");
84            assert!(
85                feature["inputParamsSchema"].is_object(),
86                "{short}: inputParamsSchema object"
87            );
88            assert!(
89                feature["displayBuilder"].is_boolean(),
90                "{short}: displayBuilder flag"
91            );
92            types.insert(short.to_string());
93        }
94        for required in [
95            "D", "P", "S", "SP", "PORT", "HX", "P.CU", "P.S", "P.CY", "P.CO", "P.T", "P.PY", "E",
96            "R", "LOFT", "SW", "SWP", "RIB", "TU", "B", "M", "SPL", "XFORM", "PATTERN", "F", "CH",
97            "O.S", "O.F", "PF", "DF", "THK", "H", "IMPORT3D", "SM.TAB", "SM.CF", "SM.F", "SM.HEM",
98            "SM.CUTOUT",
99        ] {
100            assert!(types.contains(required), "schema catalogue missing {required}");
101        }
102    }
103}