Skip to main content

workshop_rs/core/
signatures.rs

1/// Supplies the expected enum domain for a call argument during parsing.
2///
3/// The parser asks for the expected domain of argument `arg_index` (0-based)
4/// of the call whose Workshop catalog id is `catalog_id`. Implementations
5/// must return the domain only when the canonical signature pins exactly one;
6/// returning `None` leaves an ambiguous bare member unresolved.
7pub trait ExpectedDomain {
8    /// The expected enum domain for `arg_index` of the call with catalog id
9    /// `catalog_id`, or `None` when the signature does not pin one.
10    fn expected_domain(&self, catalog_id: &str, arg_index: usize) -> Option<&str>;
11}
12
13/// A context with no signature metadata. Ambiguous bare enum members remain
14/// structured with their catalog candidates. Used by callers that intentionally
15/// need context-free parsing.
16#[derive(Debug, Clone, Copy, Default)]
17pub struct NoExpectedDomain;
18
19impl ExpectedDomain for NoExpectedDomain {
20    fn expected_domain(&self, _catalog_id: &str, _arg_index: usize) -> Option<&str> {
21        None
22    }
23}
24
25/// A context chain: consult `first`, then fall back to `second`.
26///
27/// Callers that combine signature sources (e.g. a provider manifest followed
28/// by the canonical catalog) chain them; neither is authoritative alone.
29#[derive(Clone, Copy)]
30pub struct ChainedExpectedDomain<'a, 'b> {
31    first: &'a dyn ExpectedDomain,
32    second: &'b dyn ExpectedDomain,
33}
34
35impl<'a, 'b> ChainedExpectedDomain<'a, 'b> {
36    /// Chain two contexts, consulting `first` before `second`.
37    pub fn new(first: &'a dyn ExpectedDomain, second: &'b dyn ExpectedDomain) -> Self {
38        ChainedExpectedDomain { first, second }
39    }
40}
41
42impl ExpectedDomain for ChainedExpectedDomain<'_, '_> {
43    fn expected_domain(&self, catalog_id: &str, arg_index: usize) -> Option<&str> {
44        self.first
45            .expected_domain(catalog_id, arg_index)
46            .or_else(|| self.second.expected_domain(catalog_id, arg_index))
47    }
48}