crate::ix!();
pub fn fuzzy_map_u8<'de, D, V>(deserializer: D) -> Result<HashMap<u8, V>, D::Error>
where
D: Deserializer<'de>,
V: serde::de::DeserializeOwned,
{
let raw_map = HashMap::<String, JsonValue>::deserialize(deserializer)?;
let mut out = HashMap::with_capacity(raw_map.len());
for (k_str, val) in raw_map {
let k_u8 = fuzzy_key_to_u8(&k_str).map_err(de::Error::custom)?;
let parsed_v = match serde_json::from_value::<V>(val) {
Ok(v) => v,
Err(e) => {
let msg = format!("Failed to parse value for key='{}' => {}", k_str, e);
return Err(de::Error::custom(msg));
}
};
out.insert(k_u8, parsed_v);
}
Ok(out)
}
fn fuzzy_key_to_u8(key: &str) -> Result<u8, String> {
let raw_f = match key.parse::<f64>() {
Ok(f) => f,
Err(e) => {
let msg = format!("Cannot parse map key '{}' as float => {}", key, e);
return Err(msg);
}
};
if raw_f < 0.0 {
warn!("Key '{}' => negative => clamping to 0", key);
Ok(0)
} else if raw_f > 255.0 {
warn!("Key '{}' => >255 => clamping to 255", key);
Ok(255)
} else {
let truncated = raw_f.trunc();
if (raw_f - truncated).abs() > f64::EPSILON {
warn!("Key '{}' => float => truncating {} to {}", key, raw_f, truncated);
}
Ok(truncated as u8)
}
}