use crate::sys;
use crate::TskReturnValue;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum TskitError {
#[error("range error: {}", *.0)]
RangeError(String),
#[error("we received {} but expected {}",*got, *expected)]
ValueError { got: String, expected: String },
#[error("Invalid index")]
IndexError,
#[error("Not tracking samples in Trees")]
NotTrackingSamples,
#[error("{}", get_tskit_error_message(*code))]
ErrorCode { code: i32 },
#[error("{value:?}")]
MetadataError {
#[from]
value: crate::metadata::MetadataError,
},
#[error("{}", *.0)]
LibraryError(String),
}
impl From<crate::sys::Error> for TskitError {
fn from(error: sys::Error) -> Self {
match error {
sys::Error::Code(code) => TskitError::ErrorCode { code },
sys::Error::Message(msg) => TskitError::LibraryError(msg),
sys::Error::NullPointer => {
TskitError::LibraryError("null pointer encountered".to_owned())
}
}
}
}
pub fn panic_on_tskit_error(code: i32) {
panic_on_tskit_error!(code);
}
pub fn get_tskit_error_message(code: i32) -> String {
sys::get_tskit_error_message(code)
}
pub fn extract_error_message(x: TskReturnValue) -> Option<String> {
x.map_or_else(|e: TskitError| Some(format!("{}", e)), |_| None)
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_get_tskit_error_message() {
let m = get_tskit_error_message(0);
assert_eq!(m, "Normal exit condition. This is not an error!");
}
fn mock_error() -> TskReturnValue {
handle_tsk_return_value!(-207)
}
fn mock_success() -> TskReturnValue {
handle_tsk_return_value!(0)
}
#[test]
fn test_error_formatting() {
let x = mock_error();
let mut s: String = "nope!".to_string();
x.map_or_else(|e: TskitError| s = format!("{}", e), |_| ());
assert!(s.contains("Individual out of bounds"));
}
#[test]
fn test_extract_error_message() {
let x = mock_error();
match extract_error_message(x) {
Some(s) => assert!(s.contains("Individual out of bounds")),
None => panic!(),
}
if extract_error_message(mock_success()).is_some() {
panic!();
}
}
#[test]
fn test_anyhow_compatability() {
fn foo() -> anyhow::Result<crate::TableCollection> {
let tables = crate::TableCollection::new(1.0)?;
Ok(tables)
}
let _ = foo().unwrap();
}
}