crate::ix!();
pub fn fuzzy_u8<'de, D>(deserializer: D) -> Result<u8, D::Error>
where
D: Deserializer<'de>,
{
info!("fuzzy_u8 called");
let val: JsonValue = Deserialize::deserialize(deserializer)?;
match val {
JsonValue::Number(num) => {
trace!("fuzzy_u8 called with num: {num}");
if let Some(u) = num.as_u64() {
if u <= 255 {
Ok(u as u8)
} else {
warn!("JsonValue {} exceeds u8 max => clamping to 255", u);
Ok(255)
}
}
else if let Some(f) = num.as_f64() {
if f < 0.0 {
warn!("JsonValue {} < 0 => clamping to 0", f);
return Ok(0);
} else if f > 255.0 {
warn!("JsonValue {} > 255 => clamping to 255", f);
return Ok(255);
} else {
let truncated = f.trunc();
if (f - truncated).abs() > f64::EPSILON {
warn!("Truncating float {} => {}", f, truncated);
}
Ok(truncated as u8)
}
}
else {
let msg = format!("Number is not a valid int or float => {:?}", num);
Err(de::Error::custom(msg))
}
}
other => {
let msg = format!("Expected numeric, got {:?}", other);
Err(de::Error::custom(msg))
}
}
}
pub fn fuzzy_u8_from_value(val: &JsonValue) -> Result<u8, String> {
match val {
JsonValue::Number(num) => {
if let Some(u) = num.as_u64() {
if u > 255 {
warn!("JsonValue {} > 255 => clamping to 255", u);
Ok(255)
} else {
Ok(u as u8)
}
}
else if let Some(f) = num.as_f64() {
if f < 0.0 {
warn!("Float {} < 0 => clamping to 0", f);
Ok(0)
} else if f > 255.0 {
warn!("Float {} > 255 => clamping to 255", f);
Ok(255)
} else {
let truncated = f.trunc();
if (f - truncated).abs() > f64::EPSILON {
warn!("Truncating float {} => {}", f, truncated);
}
Ok(truncated as u8)
}
} else {
Err(format!("Number is not convertible to u64/f64 => {:?}", num))
}
}
other => Err(format!("Expected numeric for fuzzy_u8, got {:?}", other)),
}
}
pub fn fuzzy_key_to_u8(key: &str) -> Result<u8, String> {
match key.parse::<f64>() {
Ok(f) => {
if f < 0.0 {
warn!("fuzzy_key_to_u8: negative => clamping to 0 for key='{}'", key);
Ok(0)
} else if f > 255.0 {
warn!("fuzzy_key_to_u8: above 255 => clamping to 255 for key='{}'", key);
Ok(255)
} else {
let truncated = f.trunc();
if (f - truncated).abs() > f64::EPSILON {
warn!("fuzzy_key_to_u8: truncating {} => {}", f, truncated);
}
Ok(truncated as u8)
}
}
Err(e) => {
let msg = format!("fuzzy_key_to_u8: cannot parse '{}' => {}", key, e);
Err(msg)
}
}
}