aqc_text_engine_core/requirement/
merge.rs1use aqc_file_engine_core::{
4 ConflictEntry, ItemRequirements, Provenance, Resolve, ResolvedItemRequirements,
5 ResolvedRequirement, ScalarAssertion, resolve_items,
6};
7
8use super::{ResolvedTextFileRequirements, TextFileRequirements, TextSnippet};
9
10type TextRequirementInput = Vec<(Provenance, TextFileRequirements)>;
12type TextMergeOutput = (ResolvedTextFileRequirements, Vec<ConflictEntry>);
14
15impl TextFileRequirements {
16 #[must_use]
17 #[allow(
18 clippy::needless_pass_by_value,
19 reason = "merged_reconcile passes owned typed requirements to every engine merge function."
20 )]
21 pub fn merge(reqs: TextRequirementInput) -> TextMergeOutput {
22 let mut conflicts = Vec::new();
23 let exact_contents = resolve_optional_scalar(
24 "exact_contents",
25 &reqs,
26 |req| req.exact_contents.clone(),
27 &mut conflicts,
28 );
29 let required_snippets = resolve_snippets(
30 "required_snippets",
31 &reqs,
32 |req| req.required_snippets.clone(),
33 &mut conflicts,
34 );
35 (
36 ResolvedTextFileRequirements {
37 exact_contents,
38 required_snippets,
39 },
40 conflicts,
41 )
42 }
43}
44
45fn resolve_optional_scalar<T>(
47 key: &str,
48 items: &[(Provenance, TextFileRequirements)],
49 get: impl Fn(&TextFileRequirements) -> Option<ScalarAssertion<T>>,
50 conflicts: &mut Vec<ConflictEntry>,
51) -> Option<ResolvedRequirement<ScalarAssertion<T>, ScalarAssertion<T>>>
52where
53 T: aqc_file_engine_core::ScalarValue,
54{
55 let assertions = items
56 .iter()
57 .filter_map(|(prov, req)| get(req).map(|assertion| (prov.clone(), assertion)))
58 .collect::<Vec<_>>();
59 if assertions.is_empty() {
60 None
61 } else {
62 ScalarAssertion::<T>::resolve(key, assertions, conflicts)
63 }
64}
65
66fn resolve_snippets(
68 key: &str,
69 items: &[(Provenance, TextFileRequirements)],
70 get: impl Fn(&TextFileRequirements) -> ItemRequirements<TextSnippet>,
71 conflicts: &mut Vec<ConflictEntry>,
72) -> ResolvedItemRequirements<TextSnippet> {
73 resolve_items(
74 key,
75 items
76 .iter()
77 .map(|(prov, req)| (prov.clone(), get(req)))
78 .collect(),
79 conflicts,
80 )
81}