use std::{ffi, os::raw::c_int};
use crate::sys;
use parse_display::Display;
use thiserror::Error;
#[derive(Debug, Display)]
#[repr(u32)]
pub enum ExitCode {
Ok = sys::JIM_OK,
Err = sys::JIM_ERR,
Return = sys::JIM_RETURN,
Break = sys::JIM_BREAK,
Continue = sys::JIM_CONTINUE,
Signal = sys::JIM_SIGNAL,
Exit = sys::JIM_EXIT,
#[display("format")]
InvalidCode(u32),
}
impl From<u32> for ExitCode {
fn from(value: u32) -> Self {
match value {
sys::JIM_OK => ExitCode::Ok,
sys::JIM_ERR => ExitCode::Err,
sys::JIM_RETURN => ExitCode::Return,
sys::JIM_BREAK => ExitCode::Break,
sys::JIM_CONTINUE => ExitCode::Continue,
sys::JIM_SIGNAL => ExitCode::Signal,
sys::JIM_EXIT => ExitCode::Exit,
x => ExitCode::InvalidCode(x),
}
}
}
impl Into<c_int> for ExitCode {
fn into(self) -> c_int {
let ec: u32 = self.into();
ec as c_int
}
}
impl Into<u32> for ExitCode {
fn into(self) -> u32 {
match self {
ExitCode::Ok => sys::JIM_OK,
ExitCode::Err => sys::JIM_ERR,
ExitCode::Return => sys::JIM_RETURN,
ExitCode::Break => sys::JIM_BREAK,
ExitCode::Continue => sys::JIM_CONTINUE,
ExitCode::Signal => sys::JIM_SIGNAL,
ExitCode::Exit => sys::JIM_EXIT,
ExitCode::InvalidCode(c) => c,
}
}
}
#[derive(Error, Debug)]
pub enum JimError {
#[error("Tcl evaluation error: {0}")]
Error(String),
#[error("Tcl return code {0}")]
OtherCode(ExitCode),
#[error("Jim object is null")]
NullObject,
#[error("Input string has null character")]
NullCharacter,
}
impl From<ffi::NulError> for JimError {
fn from(_value: ffi::NulError) -> Self {
JimError::NullCharacter
}
}
pub type JimResult<T> = Result<T, JimError>;