backhopper_core/model/
check_payload.rs1use std::collections::{BTreeMap, BTreeSet};
10
11use serde::{Deserialize, Serialize};
12
13use crate::model::apply::ApplyForecast;
14use crate::model::batch::PinPayload;
15use crate::model::evaluation::{
16 AggregateVerdict, BehaviourModuleMissingFinding, HeaderFileMissingFinding,
17 SeriesEvaluationView, TestModuleSymbolMissingFinding, VersionedMachineSnapshotMissingFinding,
18 WireConstantBindingsMissingFinding,
19};
20use crate::model::findings::TargetFindings;
21use crate::model::fingerprint::VerdictFingerprint;
22use crate::model::names::{ModuleName, ProjectName, RelativePath, SeriesName, TagName};
23use crate::model::pin::Pin;
24use crate::model::pr_commit::PrCommit;
25use crate::model::resolver_coverage::ResolverCoverage;
26use crate::model::summary::VerdictKind;
27use crate::model::verdict::{Diagnostics, PinVerdict, Reason, SeriesVerdict};
28
29#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
32#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
33pub struct ProjectSuggestion {
34 pub name: String,
35 pub modules: Vec<String>,
36 pub call_sites: usize,
37}
38
39#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
42#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
43#[serde(tag = "kind", rename_all = "snake_case")]
44pub enum QueriedAgainst {
45 Pin { project: ProjectName, tag: TagName },
47 Series {
49 name: SeriesName,
50 pins: Vec<PinPayload>,
51 },
52}
53
54#[derive(Debug, Clone, Serialize, Deserialize)]
56#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
57pub struct CheckPayload {
58 pub queried_against: QueriedAgainst,
60 pub results: SeriesVerdict,
62 #[serde(default, skip_serializing_if = "Diagnostics::is_empty")]
64 pub diagnostics: Diagnostics,
65 #[serde(default, skip_serializing_if = "Vec::is_empty")]
67 pub project_suggestions: Vec<ProjectSuggestion>,
68 #[serde(default)]
72 pub pr_commits: Option<Vec<PrCommit>>,
73 #[serde(default)]
76 pub self_projects: Option<BTreeSet<ProjectName>>,
77 #[serde(default, skip_serializing_if = "Option::is_none")]
80 pub verdict_fingerprint: Option<VerdictFingerprint>,
81 #[serde(default)]
84 pub resolver_coverage: Option<ResolverCoverage>,
85 #[serde(default)]
87 pub fingerprint_version: Option<u32>,
88 #[serde(default, skip_serializing_if = "Option::is_none")]
91 pub apply: Option<ApplyForecast>,
92 #[serde(default, skip_serializing_if = "Option::is_none")]
94 pub target_findings: Option<TargetFindings>,
95}
96
97impl CheckPayload {
98 #[must_use]
102 pub fn view(&self) -> SeriesEvaluationView<'_> {
103 SeriesEvaluationView::new(&self.results, &self.diagnostics)
104 }
105
106 #[must_use]
109 pub fn tracked_refs(&self) -> Option<u32> {
110 self.self_projects
111 .as_ref()
112 .map(|projects| self.view().tracked_refs(projects))
113 }
114
115 #[must_use]
117 pub fn worst_verdict(&self) -> AggregateVerdict {
118 self.view().worst_verdict()
119 }
120
121 #[must_use]
123 pub fn has_blocking_reason(&self) -> bool {
124 self.view().has_blocking_reason()
125 }
126
127 pub fn pins_in(&self, verdict: VerdictKind) -> impl Iterator<Item = &PinVerdict> {
129 self.view().pins_in(verdict)
130 }
131
132 pub fn reasons_for(&self, pin: &Pin) -> impl Iterator<Item = &Reason> {
134 self.view().reasons_for(pin)
135 }
136
137 #[must_use]
139 pub fn pin_by_project(&self, project: &ProjectName) -> Option<&PinVerdict> {
140 self.view().pin_by_project(project)
141 }
142
143 #[must_use]
145 pub fn missing_test_modules(&self) -> &BTreeMap<RelativePath, BTreeMap<ModuleName, usize>> {
146 self.view().missing_test_modules()
147 }
148
149 pub fn test_module_symbol_missing(
151 &self,
152 ) -> impl Iterator<Item = TestModuleSymbolMissingFinding<'_>> {
153 self.view().test_module_symbol_missing()
154 }
155
156 pub fn header_file_missing(&self) -> impl Iterator<Item = HeaderFileMissingFinding<'_>> {
158 self.view().header_file_missing()
159 }
160
161 pub fn behaviour_module_missing(
163 &self,
164 ) -> impl Iterator<Item = BehaviourModuleMissingFinding<'_>> {
165 self.view().behaviour_module_missing()
166 }
167
168 pub fn versioned_machine_snapshot_missing(
170 &self,
171 ) -> impl Iterator<Item = VersionedMachineSnapshotMissingFinding<'_>> {
172 self.view().versioned_machine_snapshot_missing()
173 }
174
175 pub fn wire_constant_bindings_missing(
177 &self,
178 ) -> impl Iterator<Item = WireConstantBindingsMissingFinding<'_>> {
179 self.view().wire_constant_bindings_missing()
180 }
181}