use std::fmt;
#[derive(Debug)]
pub enum InstallationStatusError {
Json(serde_json::Error),
MissingModuleHash,
InvalidModuleHash,
}
impl fmt::Display for InstallationStatusError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Json(source) => write!(formatter, "parse icp canister status JSON: {source}"),
Self::MissingModuleHash => {
formatter.write_str("icp canister status JSON omitted module_hash")
}
Self::InvalidModuleHash => {
formatter.write_str("icp canister status JSON has an invalid module_hash")
}
}
}
}
impl std::error::Error for InstallationStatusError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Json(source) => Some(source),
Self::MissingModuleHash | Self::InvalidModuleHash => None,
}
}
}
pub fn decode_installation_status(input: &[u8]) -> Result<bool, InstallationStatusError> {
let status: serde_json::Value =
serde_json::from_slice(input).map_err(InstallationStatusError::Json)?;
match status.get("module_hash") {
Some(serde_json::Value::Null) => Ok(false),
Some(serde_json::Value::String(_)) => Ok(true),
Some(_) => Err(InstallationStatusError::InvalidModuleHash),
None => Err(InstallationStatusError::MissingModuleHash),
}
}