Skip to main content

fallow_cli/report/ci/
mod.rs

1pub mod diff_filter;
2pub(crate) mod fingerprint;
3pub mod pr_comment;
4pub mod review;
5pub(crate) mod suggestion;
6
7pub(crate) const TYPE_AWARE_INCOMPLETE_MESSAGE: &str =
8    "Required type-aware analysis was incomplete; this result is not a clean semantic report.";
9
10const SAVED_TYPE_AWARE_META_POINTERS: [&str; 4] = [
11    "/_meta/type_aware",
12    "/_meta/check/type_aware",
13    "/check/_meta/type_aware",
14    "/dead_code/_meta/type_aware",
15];
16
17pub(crate) fn saved_type_aware_metadata(
18    envelope: &serde_json::Value,
19) -> Result<Vec<fallow_types::envelope::TypeAwareMeta>, String> {
20    let mut metadata = Vec::new();
21    for pointer in SAVED_TYPE_AWARE_META_POINTERS {
22        let Some(value) = envelope.pointer(pointer).filter(|value| !value.is_null()) else {
23            continue;
24        };
25        let meta = serde_json::from_value(value.clone()).map_err(|error| {
26            format!(
27                "saved type-aware metadata at `{pointer}` is incompatible with this Fallow version: {error}"
28            )
29        })?;
30        metadata.push(meta);
31    }
32    Ok(metadata)
33}
34
35#[must_use]
36pub(crate) fn required_type_aware_incomplete(
37    meta: Option<&fallow_types::envelope::TypeAwareMeta>,
38) -> bool {
39    let Some(meta) = meta else {
40        return false;
41    };
42    if meta.required_completeness
43        != Some(fallow_types::semantic::SemanticCompletenessRequirement::Complete)
44    {
45        return false;
46    }
47    meta.identity.as_ref().is_none_or(|identity| {
48        identity.completeness != fallow_types::semantic::SemanticCompleteness::Complete
49    }) || meta
50        .queries
51        .iter()
52        .any(|query| query.status != fallow_types::semantic::SemanticCompleteness::Complete)
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58    use fallow_types::envelope::TypeAwareMeta;
59    use fallow_types::semantic::SemanticCompletenessRequirement;
60
61    #[test]
62    fn required_type_aware_metadata_without_identity_is_incomplete() {
63        let meta = TypeAwareMeta {
64            required_completeness: Some(SemanticCompletenessRequirement::Complete),
65            ..TypeAwareMeta::default()
66        };
67        assert!(required_type_aware_incomplete(Some(&meta)));
68    }
69}