use thiserror::Error;
use crate::ConstString;
#[derive(Error, Debug)]
pub enum Error {
#[error("cannot create entry with name '{name}' as it already exist")]
AlreadyExists {
name: ConstString,
},
#[error("name '{name}' is already remapped as '{remapped}'")]
AlreadyRemapped {
name: ConstString,
remapped: ConstString,
},
#[error("remapping of '{name}' contains an assignment of {value}")]
Assignment {
name: ConstString,
value: ConstString,
},
#[error("could not convert '{value}' to type of port {port}")]
ConversionFromStr {
value: ConstString,
port: ConstString,
},
#[error("cannot create a remapping target from '{name}'")]
CreateRemapping {
name: ConstString,
},
#[error("the entry for the name '{name}' is stored with a different type")]
DataType {
name: ConstString,
},
#[error("the entry '{name}' is locked")]
IsLocked {
name: ConstString,
},
#[error("remapping of '{name}' to '{remapped}' without a parent board")]
NoParent {
name: ConstString,
remapped: ConstString,
},
#[error("no remapping target for '{name}' defined")]
NoTarget {
name: ConstString,
},
#[error("an entry for the name '{name}' is not existing")]
NotFound {
name: ConstString,
},
#[error("port '{name}' has no valid value set")]
NoValue {
name: ConstString,
},
#[error("port '{port}' has an unkonwn type")]
UnknownType {
port: ConstString,
},
#[error("an unexpected error occured in '{0}' at line '{1}'")]
Unreachable(ConstString, u32),
}
impl From<Error> for dataport::Error {
fn from(value: Error) -> Self {
match value {
Error::AlreadyExists { .. } | Error::AlreadyRemapped { .. } => Self::AlreadyExists,
Error::Assignment { name, value } => Self::ReturnTypeMismatch { port: name, value },
Error::CreateRemapping { .. } => Self::ParseValue,
Error::ConversionFromStr { .. } => Self::FromStr,
Error::IsLocked { .. } => Self::IsLocked,
Error::NoParent { name, .. } | Error::NoTarget { name } | Error::NotFound { name } => Self::NotFound { name },
Error::NoValue { .. } => Self::NoValueSet,
Error::DataType { .. } | Error::UnknownType { .. } => Self::DataType,
Error::Unreachable(name, _line) => Self::NotFound { name }, }
}
}
#[cfg(test)]
mod tests {
use super::*;
const fn is_normal<T: Sized + Send + Sync>() {}
#[test]
const fn normal_types() {
is_normal::<Error>();
}
#[test]
fn from_already_exists() {
let err = Error::AlreadyExists { name: "x".into() };
assert!(matches!(dataport::Error::from(err), dataport::Error::AlreadyExists));
}
#[test]
fn from_already_remapped() {
let err = Error::AlreadyRemapped {
name: "x".into(),
remapped: "y".into(),
};
assert!(matches!(dataport::Error::from(err), dataport::Error::AlreadyExists));
}
#[test]
fn from_assignment() {
let err = Error::Assignment {
name: "p".into(),
value: "v".into(),
};
assert!(matches!(
dataport::Error::from(err),
dataport::Error::ReturnTypeMismatch { .. }
));
}
#[test]
fn from_create_remapping() {
let err = Error::CreateRemapping { name: "x".into() };
assert!(matches!(dataport::Error::from(err), dataport::Error::ParseValue));
}
#[test]
fn from_conversion_from_str() {
let err = Error::ConversionFromStr {
value: "v".into(),
port: "p".into(),
};
assert!(matches!(dataport::Error::from(err), dataport::Error::FromStr));
}
#[test]
fn from_is_locked() {
let err = Error::IsLocked { name: "x".into() };
assert!(matches!(dataport::Error::from(err), dataport::Error::IsLocked));
}
#[test]
fn from_no_parent() {
let err = Error::NoParent {
name: "x".into(),
remapped: "y".into(),
};
assert!(matches!(dataport::Error::from(err), dataport::Error::NotFound { .. }));
}
#[test]
fn from_no_target() {
let err = Error::NoTarget { name: "x".into() };
assert!(matches!(dataport::Error::from(err), dataport::Error::NotFound { .. }));
}
#[test]
fn from_not_found() {
let err = Error::NotFound { name: "x".into() };
assert!(matches!(dataport::Error::from(err), dataport::Error::NotFound { .. }));
}
#[test]
fn from_no_value() {
let err = Error::NoValue { name: "x".into() };
assert!(matches!(dataport::Error::from(err), dataport::Error::NoValueSet));
}
#[test]
fn from_data_type() {
let err = Error::DataType { name: "x".into() };
assert!(matches!(dataport::Error::from(err), dataport::Error::DataType));
}
#[test]
fn from_unreachable() {
let err = Error::Unreachable("x".into(), 42);
assert!(matches!(dataport::Error::from(err), dataport::Error::NotFound { .. }));
}
}