Skip to main content

powerio/
codes.rs

1//! The facade's diagnostic code registry. An emission site names an entry
2//! rather than a loose string.
3
4use powerio_core::DiagnosticInfo;
5
6mod facade {
7    powerio_core::diagnostic_codes! {
8        REQUEST_SINCAL_OPTIONS_PROFILE = "REQUEST.PARSE.SINCAL_OPTIONS_PROFILE", Error,
9            "multiconductor SINCAL options require the matching explicit profile", category = Request;
10        REQUEST_PARSE_POWERIO_IR = "REQUEST.PARSE.POWERIO_IR", Error,
11            "PowerIO IR is decoded with deserialize, not parse", category = Request;
12        READ_MODULE_UNSUPPORTED = "READ.MODULE.UNSUPPORTED", Error,
13            "the stored module names a schema or version this build does not read", category = Request;
14        READ_MODULE_INVALID = "READ.MODULE.INVALID", Error,
15            "the stored module document is structurally invalid", category = Data;
16        VALIDATE_COLLECTION_EMPTY = "VALIDATE.COLLECTION.EMPTY", Error,
17            "a dynamically constructed collection needs at least one value to infer its type", category = Data;
18        VALIDATE_COLLECTION_ELEMENT_TYPE = "VALIDATE.COLLECTION.ELEMENT_TYPE", Error,
19            "all values in a collection must have the same supported structural type", category = Data;
20        REQUEST_EMIT_INVALID_OPTIONS = "REQUEST.EMIT.INVALID_OPTIONS", Error,
21            "emission options do not apply to the requested format or value", category = Request;
22        EMIT_SINCAL_PACKAGING_FAILED = "EMIT.MODULE.SINCAL_PACKAGING_FAILED", Error,
23            "experimental native SINCAL container construction failed", category = Output;
24
25        // Failures.
26        REQUEST_MODULE_WRONG_MODEL_KIND = "REQUEST.MODULE.WRONG_MODEL_KIND", Error,
27            "the call asks for a model family the document does not carry", category = Request;
28        TRANSFORM_LINDIST3FLOW_OPTIONS_SERIALIZE_FAILED =
29            "TRANSFORM.LINDIST3FLOW.OPTIONS_SERIALIZE_FAILED", Error,
30            "serializing LinDist3Flow options for transform history failed", category = Output;
31        EMIT_MODULE_SERIALIZE_FAILED = "EMIT.MODULE.SERIALIZE_FAILED", Error,
32            "serializing the stored document to JSON failed", category = Output;
33        EMIT_MODULE_RECORD_CAP = "EMIT.MODULE.RECORD_CAP", Error,
34            "a stored record would exceed a bound the PowerIO IR reader enforces",
35            category = Request;
36    }
37}
38
39#[doc(inline)]
40pub use facade::*;
41#[doc(inline)]
42pub use powerio_tnd::diagnostics::*;
43
44/// Every code this crate declares or re-exports, in registry order. As in
45/// 0.11.5 it includes the transformation codes, which now live in tnd.
46pub const ALL: &[&DiagnosticInfo] = &concat::<
47    { facade::ALL.len() + powerio_tnd::diagnostics::ALL.len() },
48>(facade::ALL, powerio_tnd::diagnostics::ALL);
49
50const fn concat<const N: usize>(
51    first: &[&'static DiagnosticInfo],
52    second: &[&'static DiagnosticInfo],
53) -> [&'static DiagnosticInfo; N] {
54    assert!(first.len() + second.len() == N);
55    let mut all = [first[0]; N];
56    let mut i = 1;
57    while i < N {
58        all[i] = if i < first.len() {
59            first[i]
60        } else {
61            second[i - first.len()]
62        };
63        i += 1;
64    }
65    all
66}
67
68/// Every code this crate declares.
69#[must_use]
70pub fn registry() -> Vec<&'static DiagnosticInfo> {
71    ALL.to_vec()
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77
78    #[test]
79    fn the_registry_is_sound() {
80        let problems = powerio_core::check_registry(registry());
81        assert!(problems.is_empty(), "{problems:#?}");
82    }
83
84    #[test]
85    fn all_keeps_every_code_the_facade_listed_in_0_11_5() {
86        assert_eq!(
87            ALL.len(),
88            facade::ALL.len() + powerio_tnd::diagnostics::ALL.len()
89        );
90        for code in powerio_tnd::diagnostics::ALL {
91            assert!(
92                ALL.iter().any(|listed| listed.code == code.code),
93                "{}",
94                code.code
95            );
96        }
97        assert!(
98            ALL.iter()
99                .any(|code| code.code == "TRANSFORM.MULTI_TO_BALANCED.AMBIGUOUS_TERMINAL_MAP")
100        );
101    }
102}