Skip to main content

callisto_graph/
napi.rs

1use std::collections::BTreeMap;
2use std::path::Path;
3
4use callisto_model::{Diagnostic, DiagnosticCode, DiagnosticSeverity, ManifestRole, StrictFlag};
5
6use crate::config::{GroupDef, GroupTable};
7
8#[derive(Clone, Debug, Default)]
9pub struct NapiTargetsIndex {
10    declared: BTreeMap<callisto_model::GroupName, Vec<String>>,
11}
12
13impl NapiTargetsIndex {
14    pub fn load(groups: &GroupTable, _root: &Path) -> Result<Self, callisto_model::ManifestError> {
15        let mut declared = BTreeMap::new();
16        for g in groups.fixed.values() {
17            declared.insert(g.name.clone(), Vec::new());
18        }
19        Ok(NapiTargetsIndex { declared })
20    }
21
22    pub fn declared_for(&self, group: &callisto_model::GroupName) -> Option<&[String]> {
23        self.declared.get(group).map(|v| v.as_slice())
24    }
25}
26
27pub fn napi_drift(group: &GroupDef, declared: &[String], _root: &Path) -> Vec<Diagnostic> {
28    let mut diagnostics = Vec::new();
29    let declared_triples: Vec<String> = declared.iter().map(|s| s.trim().to_string()).collect();
30
31    for t in &declared_triples {
32        diagnostics.push(Diagnostic {
33            code: DiagnosticCode::NapiTargetAddedNotInMembers,
34            severity: DiagnosticSeverity::Warning,
35            message: format!(
36                "`napi.targets` declares `{t}`, which is not in fixed group `{}`'s members; accept it with `callisto init`",
37                group.name
38            ),
39            package: None,
40            path: None,
41            governed_by: None,
42            escalated_by: Some(StrictFlag::Strict),
43        });
44    }
45
46    diagnostics
47}
48
49pub fn triple_to_role(triple: &str) -> Option<ManifestRole> {
50    let parts: Vec<&str> = triple.split('-').collect();
51    if parts.len() >= 3 {
52        let arch = parts[0].to_string();
53        let platform = parts[2].to_string();
54        Some(ManifestRole::Platform {
55            platform,
56            arch,
57            abi: None,
58        })
59    } else {
60        None
61    }
62}
63
64pub fn role_to_triple(role: &ManifestRole) -> Option<String> {
65    if let ManifestRole::Platform {
66        platform,
67        arch,
68        abi,
69    } = role
70    {
71        Some(format!(
72            "{}-{}-{}",
73            arch,
74            platform,
75            abi.as_deref().unwrap_or("gnu")
76        ))
77    } else {
78        None
79    }
80}