use crate::TskReturnValue;
use thiserror::Error;
#[derive(Error, Debug, PartialEq)]
pub enum TskitError {
#[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,
},
}
pub fn panic_on_tskit_error(code: i32) {
panic_on_tskit_error!(code);
}
pub fn get_tskit_error_message(code: i32) -> String {
let c_str = unsafe { std::ffi::CStr::from_ptr(crate::bindings::tsk_strerror(code)) };
c_str.to_str().unwrap().to_owned()
}
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_eq!(s, "Individual out of bounds");
}
#[test]
fn test_extract_error_message() {
let x = mock_error();
match extract_error_message(x) {
Some(s) => assert_eq!(s, "Individual out of bounds"),
None => panic!(),
}
if extract_error_message(mock_success()).is_some() {
panic!();
}
}
}