Skip to main content

omena_resolver/
source_runtime.rs

1use super::*;
2
3pub fn summarize_omena_resolver_query_fragments(
4    input: &EngineInputV2,
5) -> SourceResolutionQueryFragmentsV0 {
6    summarize_source_resolution_query_fragments_input(input)
7}
8
9pub fn summarize_omena_resolver_canonical_producer_signal(
10    input: &EngineInputV2,
11) -> SourceResolutionCanonicalProducerSignalV0 {
12    summarize_source_resolution_canonical_producer_signal_input(input)
13}
14
15pub fn summarize_omena_resolver_source_resolution_runtime(
16    input: &EngineInputV2,
17) -> OmenaResolverSourceResolutionRuntimeIndexV0 {
18    let canonical_signal = summarize_omena_resolver_canonical_producer_signal(input);
19    let mut candidates_by_expression = BTreeMap::<String, SourceResolutionCandidateV0>::new();
20
21    for candidate in canonical_signal.canonical_bundle.candidates {
22        candidates_by_expression.insert(candidate.expression_id.clone(), candidate);
23    }
24
25    let entries = canonical_signal
26        .canonical_bundle
27        .query_fragments
28        .iter()
29        .map(|fragment| {
30            runtime_source_resolution_entry_from_fragment(
31                fragment,
32                candidates_by_expression.get(&fragment.expression_id),
33            )
34        })
35        .collect::<Vec<_>>();
36    let resolved_expression_count = entries
37        .iter()
38        .filter(|entry| entry.can_resolve_source_expression)
39        .count();
40    let unresolved_expression_count = entries.len() - resolved_expression_count;
41    let mut blocking_gaps = Vec::new();
42
43    if entries.is_empty() {
44        blocking_gaps.push("emptySourceResolutionRuntimeIndex");
45    }
46    if unresolved_expression_count > 0 {
47        blocking_gaps.push("unresolvedSourceExpressions");
48    }
49
50    OmenaResolverSourceResolutionRuntimeIndexV0 {
51        schema_version: "0",
52        product: "omena-resolver.source-resolution-runtime-index",
53        input_product: "engine-input-producers.source-resolution-canonical-producer",
54        input_version: canonical_signal.input_version,
55        expression_count: entries.len(),
56        resolved_expression_count,
57        unresolved_expression_count,
58        blocking_gaps,
59        entries,
60    }
61}
62
63pub fn query_omena_resolver_source_expression(
64    runtime_index: &OmenaResolverSourceResolutionRuntimeIndexV0,
65    expression_id: &str,
66) -> Option<OmenaResolverSourceResolutionRuntimeEntryV0> {
67    runtime_index
68        .entries
69        .iter()
70        .find(|entry| entry.expression_id == expression_id)
71        .cloned()
72}
73
74fn runtime_source_resolution_entry_from_fragment(
75    fragment: &SourceResolutionQueryFragmentV0,
76    candidate: Option<&SourceResolutionCandidateV0>,
77) -> OmenaResolverSourceResolutionRuntimeEntryV0 {
78    let selector_names = candidate
79        .map(|candidate| candidate.selector_names.clone())
80        .unwrap_or_default();
81    let finite_values = candidate.and_then(|candidate| candidate.finite_values.clone());
82    let has_selector_match = !selector_names.is_empty();
83    let has_finite_values = finite_values
84        .as_ref()
85        .is_some_and(|values| !values.is_empty());
86
87    OmenaResolverSourceResolutionRuntimeEntryV0 {
88        query_id: fragment.query_id.clone(),
89        expression_id: fragment.expression_id.clone(),
90        expression_kind: fragment.expression_kind.clone(),
91        style_file_path: fragment.style_file_path.clone(),
92        selector_names,
93        finite_values,
94        selector_certainty: candidate
95            .map(|candidate| candidate.selector_certainty.clone())
96            .unwrap_or_else(|| "unresolved".to_string()),
97        value_certainty: candidate.and_then(|candidate| candidate.value_certainty.clone()),
98        selector_certainty_shape_kind: candidate
99            .map(|candidate| candidate.selector_certainty_shape_kind.clone())
100            .unwrap_or_else(|| "missingTypeFacts".to_string()),
101        value_certainty_shape_kind: candidate
102            .map(|candidate| candidate.value_certainty_shape_kind.clone())
103            .unwrap_or_else(|| "missingTypeFacts".to_string()),
104        has_selector_match,
105        has_finite_values,
106        can_resolve_source_expression: has_selector_match,
107        status: if has_selector_match {
108            "resolved"
109        } else if candidate.is_some() {
110            "unresolvedSelectorSet"
111        } else {
112            "missingTypeFacts"
113        },
114    }
115}