omena_resolver/
source_runtime.rs1use 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}