1use crate::classify::{classify, missing_sections};
6use crate::parse::Artifact;
7use crate::spec::{spec_for, ArtifactSpec};
8
9pub fn supports_improve(spec: &ArtifactSpec) -> bool {
13 spec.expected()
14 .iter()
15 .all(|section| spec.guidance.iter().any(|(k, _)| k == section))
16}
17
18pub struct ImprovementResult {
21 pub artifact_type: String,
23 pub missing_required: Vec<String>,
24 pub missing_recommended: Vec<String>,
25 pub guidance: Vec<(String, Vec<String>)>,
28 pub supported: bool,
30}
31
32pub fn improve_product(artifact: &Artifact) -> ImprovementResult {
34 let artifact_type = classify(artifact).artifact_type;
35 let spec = spec_for(&artifact_type);
36 let Some(spec) = spec.filter(|s| supports_improve(s)) else {
37 return ImprovementResult {
39 artifact_type,
40 missing_required: Vec::new(),
41 missing_recommended: Vec::new(),
42 guidance: Vec::new(),
43 supported: false,
44 };
45 };
46 let (missing_required, missing_recommended) = missing_sections(artifact, spec);
47 let mut guidance: Vec<(String, Vec<String>)> = Vec::new();
48 for s in missing_required.iter().chain(missing_recommended.iter()) {
49 if let Some((_, g)) = spec.guidance.iter().find(|(k, _)| k == s) {
51 if !g.is_empty() {
52 guidance.push((s.clone(), g.clone()));
53 }
54 }
55 }
56 ImprovementResult {
57 artifact_type,
58 missing_required,
59 missing_recommended,
60 guidance,
61 supported: true,
62 }
63}