use pico_de_gallo_lib::host_client::HostErr;
use pico_de_gallo_lib::{PicoDeGalloError, ValidateError, WireError};
use rmcp::ErrorData;
fn is_no_device(err: &HostErr<WireError>) -> bool {
matches!(err, HostErr::Closed)
}
pub fn map_pdg_err<E: core::fmt::Display>(err: PicoDeGalloError<E>) -> ErrorData {
match err {
PicoDeGalloError::Comms(e) if is_no_device(&e) => ErrorData::internal_error(
"no device attached: connect a Pico de Gallo and retry".to_string(),
None,
),
PicoDeGalloError::Comms(e) => {
ErrorData::internal_error(format!("communication error: {e:?}"), None)
}
PicoDeGalloError::Endpoint(e) => {
ErrorData::invalid_params(format!("device error: {e}"), None)
}
}
}
pub fn map_validate_err(err: ValidateError) -> ErrorData {
match err {
ValidateError::Comms(e) if is_no_device(&e) => ErrorData::internal_error(
"no device attached: connect a Pico de Gallo and retry".to_string(),
None,
),
other => ErrorData::internal_error(format!("{other}"), None),
}
}
pub fn invalid_arg(msg: impl Into<String>) -> ErrorData {
ErrorData::invalid_params(msg.into(), None)
}
#[cfg(test)]
mod tests {
use super::*;
use pico_de_gallo_lib::host_client::HostErr;
use pico_de_gallo_lib::{PicoDeGalloError, ValidateError};
#[test]
fn comms_closed_becomes_no_device_message() {
let e: PicoDeGalloError<std::convert::Infallible> =
PicoDeGalloError::Comms(HostErr::Closed);
let data = map_pdg_err(e);
assert!(
data.message.to_lowercase().contains("no device")
|| data.message.to_lowercase().contains("not attached"),
"message was: {}",
data.message
);
}
#[test]
fn endpoint_error_is_surfaced_via_display() {
let e: PicoDeGalloError<String> = PicoDeGalloError::Endpoint("NoAcknowledge".into());
let data = map_pdg_err(e);
assert!(
data.message.contains("NoAcknowledge"),
"message was: {}",
data.message
);
}
#[test]
fn validate_schema_mismatch_includes_versions() {
let e = ValidateError::SchemaMismatch {
expected_major: 0,
actual_major: 0,
expected_minor: 7,
actual_minor: 6,
};
let data = map_validate_err(e);
assert!(data.message.contains('7') && data.message.contains('6'));
}
#[test]
fn validate_legacy_firmware_message() {
let data = map_validate_err(ValidateError::LegacyFirmware);
assert!(data.message.to_lowercase().contains("firmware"));
}
}