espforge_lib/resolver/strategies/
hardware.rs1use crate::register_strategy;
4use crate::resolver::ParameterType;
5use crate::resolver::strategies::{ParameterStrategy, ResolutionContext};
6use anyhow::{Result, anyhow};
7use espforge_macros::auto_register_param_strategy;
8use serde_yaml_ng::Value;
9
10#[derive(Default)]
12#[auto_register_param_strategy(
13 ParameterType::GpioRef,
14 ParameterType::SpiRef,
15 ParameterType::I2cRef,
16 ParameterType::UartRef
17)]
18pub struct HardwareStrategy;
19
20impl ParameterStrategy for HardwareStrategy {
21 fn resolve(&self, value: &Value, ctx: &ResolutionContext) -> Result<Value> {
22 let ref_name = self.extract_name(value)?;
23
24 let hardware = ctx.hardware.ok_or_else(|| {
25 anyhow!("Hardware configuration (esp32) is required for hardware references")
26 })?;
27
28 if let Some(gpio_config) = hardware.gpio.get(ref_name) {
30 let mut map = serde_yaml_ng::Mapping::new();
31 map.insert(Value::from("pin"), Value::from(gpio_config.pin));
32 return Ok(Value::Mapping(map));
33 }
34
35 if let Some(spi_config) = hardware.spi.get(ref_name) {
37 let mut map = serde_yaml_ng::Mapping::new();
38 map.insert(Value::from("miso"), Value::from(spi_config.miso));
39 map.insert(Value::from("mosi"), Value::from(spi_config.mosi));
40 map.insert(Value::from("sck"), Value::from(spi_config.sck));
41 if let Some(cs) = spi_config.cs {
42 map.insert(Value::from("cs"), Value::from(cs));
43 } else {
44 map.insert(Value::from("cs"), Value::from(u8::MAX)); }
46 return Ok(Value::Mapping(map));
47 }
48
49 if let Some(i2c_config) = hardware.i2c.get(ref_name) {
50 return Ok(i2c_config.clone());
51 }
52
53 if let Some(uart_config) = hardware.uart.get(ref_name) {
54 return Ok(uart_config.clone());
55 }
56
57 Err(anyhow!(
58 "Undefined Hardware Reference: '${}' (checked gpio, spi)",
59 ref_name
60 ))
61 }
62}
63
64impl HardwareStrategy {
65 fn extract_name<'a>(&self, value: &'a Value) -> Result<&'a str> {
66 let val_str = value
67 .as_str()
68 .ok_or_else(|| anyhow!("Reference value must be a string"))?;
69
70 val_str
71 .strip_prefix('$')
72 .ok_or_else(|| anyhow!("Hardware reference must start with '$', got: {}", val_str))
73 }
74}