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