Skip to main content

axiolid/
integration.rs

1//! Capability handshake for the feature set compiled into the facade.
2
3use axiolid_contracts::{
4    BoundaryContract, IntegrationDescriptor, IntegrationProfile, Representation,
5};
6
7macro_rules! compiled_feature {
8    ($target:expr, $name:literal) => {
9        if cfg!(feature = $name) {
10            $target.push($name);
11        }
12    };
13}
14
15macro_rules! compiled_representation {
16    ($target:expr, $feature:literal, $representation:expr) => {
17        if cfg!(feature = $feature) {
18            $target.push($representation);
19        }
20    };
21}
22
23/// Describe the representations and features compiled into this facade build.
24///
25/// Operation features expose portable request/response traits; they are not
26/// executable capability claims. A later provider-registration step adds a
27/// `CapabilityDescriptor` only after a concrete operation provider is linked.
28pub fn descriptor() -> IntegrationDescriptor {
29    let mut descriptor = IntegrationDescriptor::empty(IntegrationProfile::RustFacade);
30    descriptor.boundary = BoundaryContract::rust();
31    descriptor.enabled_features = enabled_features();
32    descriptor.representations = enabled_representations();
33    descriptor
34}
35
36fn enabled_features() -> Vec<&'static str> {
37    let mut features = Vec::new();
38    compiled_feature!(features, "integration");
39    compiled_feature!(features, "mesh");
40    compiled_feature!(features, "linear");
41    compiled_feature!(features, "predicates");
42    compiled_feature!(features, "linear-intersection");
43    compiled_feature!(features, "profiles");
44    compiled_feature!(features, "curves");
45    compiled_feature!(features, "surfaces");
46    compiled_feature!(features, "topology");
47    compiled_feature!(features, "brep");
48    compiled_feature!(features, "primitives");
49    compiled_feature!(features, "model");
50    compiled_feature!(features, "evaluate");
51    compiled_feature!(features, "nurbs");
52    compiled_feature!(features, "tessellation");
53    compiled_feature!(features, "spatial");
54    compiled_feature!(features, "ray-mesh");
55    compiled_feature!(features, "measure");
56    compiled_feature!(features, "overlay");
57    compiled_feature!(features, "field");
58    compiled_feature!(features, "field-ops");
59    compiled_feature!(features, "field-navigation");
60    compiled_feature!(features, "heal");
61    compiled_feature!(features, "contracts");
62    compiled_feature!(features, "mesh-contracts");
63    compiled_feature!(features, "mesh-boolean");
64    compiled_feature!(features, "mesh-section");
65    compiled_feature!(features, "mesh-hidden-lines");
66    compiled_feature!(features, "graph-compile");
67    compiled_feature!(features, "dispatch-mesh-boolean");
68    compiled_feature!(features, "dispatch-mesh-section");
69    compiled_feature!(features, "dispatch-mesh-hidden-lines");
70    compiled_feature!(features, "hidden-lines-provider");
71    compiled_feature!(features, "generate");
72    compiled_feature!(features, "cpu");
73    compiled_feature!(features, "parallel");
74    compiled_feature!(features, "simd");
75    compiled_feature!(features, "gpu");
76    compiled_feature!(features, "discrete");
77    compiled_feature!(features, "parametric");
78    compiled_feature!(features, "advanced");
79    compiled_feature!(features, "application");
80    compiled_feature!(features, "portable-provider");
81    compiled_feature!(features, "full");
82    features.sort_unstable();
83    features
84}
85
86fn enabled_representations() -> Vec<Representation> {
87    let mut representations = vec![Representation::Scalar];
88    compiled_representation!(representations, "linear", Representation::Linear);
89    compiled_representation!(representations, "profiles", Representation::Profile2d);
90    compiled_representation!(representations, "curves", Representation::AnalyticCurve);
91    compiled_representation!(representations, "surfaces", Representation::AnalyticSurface);
92    compiled_representation!(representations, "topology", Representation::Topology);
93    compiled_representation!(representations, "brep", Representation::ExactBrep);
94    compiled_representation!(representations, "mesh", Representation::TriangleMesh);
95    compiled_representation!(representations, "model", Representation::ModelGraph);
96    compiled_representation!(representations, "field", Representation::SampledField);
97    representations.sort_unstable();
98    representations.dedup();
99    representations
100}
101
102#[cfg(test)]
103mod tests {
104    use super::*;
105    use axiolid_contracts::{INTEGRATION_API_VERSION, MINIMUM_RUST_VERSION};
106
107    #[test]
108    fn compiled_descriptor_is_honest_about_default_surface() {
109        let descriptor = descriptor();
110        assert_eq!(descriptor.api_version, INTEGRATION_API_VERSION);
111        assert_eq!(descriptor.minimum_rust_version, Some(MINIMUM_RUST_VERSION));
112        assert!(descriptor.enabled_features.contains(&"integration"));
113        assert!(descriptor.representations.contains(&Representation::Scalar));
114        assert!(descriptor.capabilities.is_empty());
115    }
116
117    #[test]
118    fn feature_and_representation_rows_are_unique() {
119        let descriptor = descriptor();
120        let mut features = descriptor.enabled_features.clone();
121        features.sort_unstable();
122        features.dedup();
123        assert_eq!(features, descriptor.enabled_features);
124
125        let mut representations = descriptor.representations.clone();
126        representations.sort_unstable();
127        representations.dedup();
128        assert_eq!(representations, descriptor.representations);
129    }
130}