espforge_lib/nibblers/
app.rs

1use crate::{
2    config::EspforgeConfiguration,
3    generate::load_manifests,
4    nibblers::{ConfigNibbler, NibblerResult, NibblerStatus},
5    register_nibbler,
6    resolver::actions::{ActionResolver, ValidationResult},
7};
8use espforge_macros::auto_register_nibbler;
9
10#[derive(Default)]
11#[auto_register_nibbler]
12pub struct AppNibbler;
13
14impl ConfigNibbler for AppNibbler {
15    fn name(&self) -> &str {
16        "AppNibbler"
17    }
18
19    fn priority(&self) -> u8 {
20        30
21    }
22
23    fn process(&self, config: &EspforgeConfiguration) -> Result<NibblerResult, String> {
24        let mut findings = Vec::new();
25        let mut status = NibblerStatus::Ok;
26
27        // We load manifests here to perform semantic validation (checking if methods exist)
28        // In a larger system, manifests might be passed in context, but loading here is acceptable.
29        let manifests = load_manifests().map_err(|e| e.to_string())?;
30        let resolver = ActionResolver::new();
31
32        if let Some(app) = &config.app {
33            let mut validate_block = |action_map: &std::collections::HashMap<
34                String,
35                serde_yaml_ng::Value,
36            >,
37                                      scope: &str| {
38                for (key, value) in action_map {
39                    let result = resolver.validate(key, value, config, &manifests);
40
41                    match result {
42                        ValidationResult::Ok(msg) => {
43                            findings.push(msg);
44                        }
45                        ValidationResult::Error(msg) => {
46                            findings.push(format!("Error in {}: {}", scope, msg));
47                            status = NibblerStatus::Error;
48                        }
49                        ValidationResult::Warning(msg) => {
50                            findings.push(format!("Warning in {}: {}", scope, msg));
51                            status = NibblerStatus::Warning;
52                        }
53                        ValidationResult::Ignored => {
54                            findings
55                                .push(format!("Warning in {}: Unknown action '{}'", scope, key));
56                            status = NibblerStatus::Warning;
57                        }
58                    }
59                }
60            };
61
62            for action in &app.setup {
63                validate_block(action, "app.setup");
64            }
65            for action in &app.loop_fn {
66                validate_block(action, "app.loop");
67            }
68        }
69
70        Ok(NibblerResult {
71            nibbler_name: self.name().to_string(),
72            findings,
73            status,
74        })
75    }
76}
77//register_nibbler!(AppNibbler);