1use cimmodel::CimDataset;
2use crate::Config;
3
4fn uri_to_short_name(uri: &str) -> Option<&'static str> {
7 crate::cgmes_profile_index().0.iter().find(|(iri, _)| *iri == uri).map(|(_, code)| *code)
8}
9
10fn collect_profiles_from_type(dataset: &CimDataset, type_name: &str, seen: &mut std::collections::HashSet<&'static str>) {
11 for mrid in dataset.by_type.get(type_name).into_iter().flatten() {
12 let entry = match dataset.entries.get(mrid) { Some(e) => e, None => continue };
13 let Some(model) = crate::sparql::Fields::of_class(entry, type_name) else { continue };
14 for p in model.texts("Model.profile") {
15 let p = p.trim();
16 if !p.is_empty()
17 && let Some(short) = uri_to_short_name(p) {
18 seen.insert(short);
19 }
20 }
21 }
22}
23
24pub fn detect_config(dataset: &CimDataset) -> Config {
32 let mut seen: std::collections::HashSet<&'static str> = std::collections::HashSet::new();
33 collect_profiles_from_type(dataset, "FullModel", &mut seen);
34 collect_profiles_from_type(dataset, "DifferenceModel", &mut seen);
35 for iri in conforms_to(dataset) {
36 if let Some(short) = uri_to_short_name(iri.trim()) {
37 seen.insert(short);
38 }
39 }
40
41 let mut profiles: Vec<String> = seen.iter().map(|s| s.to_string()).collect();
42 profiles.sort();
43
44 let is_solved = seen.contains("SV");
45 Config {
46 profiles,
47 solved: is_solved,
48 not_solved: !is_solved,
49 ..Config::default()
50 }
51}
52
53pub fn detect_nc_profiles(dataset: &CimDataset) -> Vec<String> {
65 let mut seen: Vec<String> = Vec::new();
66 for iri in conforms_to(dataset) {
67 if let Some(code) = nc_profile_code(iri)
68 && !seen.iter().any(|s| s == code) {
69 seen.push(code.to_string());
70 }
71 }
72 seen.sort();
73 seen
74}
75
76fn conforms_to(dataset: &CimDataset) -> impl Iterator<Item = &str> {
81 ["nc:Dataset", "nc:DifferenceSet"]
82 .into_iter()
83 .flat_map(|t| dataset.by_type.get(t).into_iter().flatten())
84 .filter_map(|mrid| dataset.entries.get(mrid))
85 .flat_map(|el| {
86 el.get_refs("conformsTo").iter().map(String::as_str).chain(el.get_str("conformsTo"))
87 })
88}
89
90pub fn nc_profile_code(iri: &str) -> Option<&'static str> {
95 let iri = iri.trim();
96 crate::nc_profile_index()
97 .0
98 .iter()
99 .find(|(known, _)| *known == iri)
100 .map(|(_, code)| *code)
101}