use num;
use num_derive::FromPrimitive;
use num_derive::ToPrimitive;
use std::cmp::Ordering;
#[derive(Debug)]
pub enum CantMakeError {
EnumNamedFromInteger(i32),
IntegerFromEnumNamed(EnumNamed),
ESTLTypeFromInteger(i32),
EReadWriteFromInteger(i32),
}
pub type Result<T> = std::result::Result<T, CantMakeError>;
#[derive(Debug, Clone, PartialEq)]
pub enum Enum {
Named(EnumNamed),
Int(i32),
}
impl Default for Enum {
fn default() -> Self {
Self::Named(EnumNamed::default())
}
}
impl From<EnumNamed> for Enum {
fn from(e: EnumNamed) -> Self {
Self::Named(e)
}
}
impl Enum {
pub fn from_i32(i: i32) -> Self {
match EnumNamed::from_i32(i) {
Ok(ii) => Self::Named(ii),
Err(_) => Enum::Int(i),
}
}
pub fn to_i32(&self) -> i32 {
match self {
Self::Named(o) => num::ToPrimitive::to_i32(o).unwrap(),
Enum::Int(i) => *i,
}
}
}
#[derive(FromPrimitive, ToPrimitive, Default, Debug, Copy, Clone, PartialEq)]
pub enum EnumNamed {
#[default]
Base = 0,
Char = 1,
Short = 2,
Int = 3,
Long = 4,
Float = 5,
Counter = 6,
CharStar = 7,
Double = 8,
Double32 = 9,
LegacyChar = 10,
UChar = 11,
UShort = 12,
UInt = 13,
ULong = 14,
Bits = 15,
Long64 = 16,
ULong64 = 17,
Bool = 18,
Float16 = 19,
OffsetL = 20,
OffsetP = 40,
OffsetP16 = 56,
Object = 61,
Any = 62,
Objectp = 63,
ObjectP = 64,
TString = 65,
TObject = 66,
TNamed = 67,
Anyp = 68,
AnyP = 69,
AnyPnoVT = 70,
STLp = 71,
Skip = 100,
SkipL = 120,
SkipP = 140,
Conv = 200,
ConvL = 220,
ConvP = 240,
Stl = 300,
STLstring = 365,
Streamer = 500,
StreamLoop = 501,
Cache = 600,
Artificial = 1000,
CacheNew = 1001,
CacheDelete = 1002,
NeedObjectForVirtualBaseClass = 99997,
Missing = 99999,
}
impl EnumNamed {
pub fn from_i32(i: i32) -> Result<Self> {
num::FromPrimitive::from_i32(i).ok_or(CantMakeError::EnumNamedFromInteger(i))
}
pub fn to_i32(self) -> Result<i32> {
num::ToPrimitive::to_i32(&self).ok_or(CantMakeError::IntegerFromEnumNamed(self))
}
pub fn from_string(s: &str) -> Result<Self> {
match s {
"int" => Ok(EnumNamed::Int),
"Int_t" => Ok(EnumNamed::Int),
"int32_t" => Ok(EnumNamed::Int),
"uint32_t" => Ok(EnumNamed::UInt),
"int8_t" => Ok(EnumNamed::Char),
"uint8_t" => Ok(EnumNamed::UChar),
"unsigned int" => Ok(EnumNamed::UInt),
"UInt_t" => Ok(EnumNamed::UInt),
"short" => Ok(EnumNamed::Short),
"Short_t" => Ok(EnumNamed::Short),
"int16_t" => Ok(EnumNamed::Short),
"unsigned short" => Ok(EnumNamed::UShort),
"UShort_t" => Ok(EnumNamed::UShort),
"uint16_t" => Ok(EnumNamed::UShort),
"int64_t" => Ok(EnumNamed::Long64),
"uint64_t" => Ok(EnumNamed::ULong64),
"float" => Ok(EnumNamed::Float),
"double" => Ok(EnumNamed::Double),
_ => unimplemented!("{} not implemented", s),
}
}
}
#[derive(FromPrimitive, ToPrimitive, Default, Debug, Clone)]
pub enum ESTLType {
#[default]
NotSTL = 0,
STLvector = 1,
STLlist = 2,
STLdeque = 3,
STLmap = 4,
STLmultimap = 5,
STLset = 6,
STLmultiset = 7,
STLbitset = 8,
STLforwardlist = 9,
STLunorderedset = 10,
STLunorderedmultiset = 11,
STLunorderedmap = 12,
STLunorderedmultimap = 13,
STLend = 14,
STLany = 300,
STLstdstring = 365,
}
impl ESTLType {
pub fn from_i32(i: i32) -> Result<Self> {
num::FromPrimitive::from_i32(i).ok_or(CantMakeError::ESTLTypeFromInteger(i))
}
}
#[derive(FromPrimitive, ToPrimitive, Default, Debug)]
pub enum EReadWrite {
#[default]
Base = 0,
OffsetL = 20,
OffsetP = 40,
Counter = 6,
CharStar = 7,
Char = 1,
Short = 2,
Int = 3,
Long = 4,
Float = 5,
Double = 8,
Double32 = 9,
UChar = 11,
UShort = 12,
UInt = 13,
ULong = 14,
Bits = 15,
Long64 = 16,
ULong64 = 17,
Bool = 18,
Float16 = 19,
Object = 61,
Any = 62,
Objectp = 63,
ObjectP = 64,
TString = 65,
TObject = 66,
TNamed = 67,
Anyp = 68,
AnyP = 69,
AnyPnoVT = 70,
STLp = 71,
Skip = 100,
SkipL = 120,
SkipP = 140,
Conv = 200,
ConvL = 220,
ConvP = 240,
Stl = 300,
STLstring = 365,
Streamer = 500,
StreamLoop = 501,
Cache = 600,
Artificial = 1000,
CacheNew = 1001,
CacheDelete = 1002,
NeedObjectForVirtualBaseClass = 99997,
Missing = 99999,
}
impl EReadWrite {
pub fn from_i32(i: i32) -> Result<Self> {
num::FromPrimitive::from_i32(i).ok_or(CantMakeError::EReadWriteFromInteger(i))
}
pub fn to_i32(&self) -> i32 {
num::ToPrimitive::to_i32(self).expect("Can not go wrong")
}
}
impl From<EReadWrite> for i32 {
fn from(e: EReadWrite) -> Self {
e.to_i32()
}
}
impl PartialEq<EReadWrite> for i32 {
fn eq(&self, other: &EReadWrite) -> bool {
*self == other.to_i32()
}
}
impl PartialOrd<EReadWrite> for i32 {
fn partial_cmp(&self, other: &EReadWrite) -> Option<Ordering> {
Some(self.cmp(&other.to_i32()))
}
}
impl PartialEq<i32> for EReadWrite {
fn eq(&self, other: &i32) -> bool {
self.to_i32() == *other
}
}
impl PartialOrd<i32> for EReadWrite {
fn partial_cmp(&self, other: &i32) -> Option<Ordering> {
Some(self.to_i32().cmp(other))
}
}
#[cfg(test)]
mod tests {
use crate::rmeta::EReadWrite;
#[test]
fn compare_eread_write() {
let offset_p_p1 = EReadWrite::OffsetP.to_i32();
assert_eq!(offset_p_p1, EReadWrite::OffsetP);
let offset_p_p1 = offset_p_p1 + 1;
assert!(offset_p_p1 > EReadWrite::OffsetP);
assert!(EReadWrite::OffsetP < offset_p_p1);
}
}