/// the e_class index in e_ident.
pub const ELF_IDENT_CLASS_INDEX: usize = 4;

/// invalid class
pub const ELF_IDENT_CLASS_NONE: u8 = 0;
/// 32-bit objects
pub const ELF_IDENT_CLASS_32: u8 = 1;
/// 64-bit objects
pub const ELF_IDENT_CLASS_64: u8 = 2;
/// the number of pre-defined e_class values.
pub const ELF_IDENT_CLASS_NUM: u8 = 3;

/// the object file's class/capacity identifier
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum ElfClass {
    /// invalid class
    None,
    /// 32-bit objects
    Class32,
    /// 64-bit objects
    Class64,
    /// the number of pre-defined e_class values.
    Num,
    /// custom value
    Any(u8),
}

impl std::fmt::Display for ElfClass {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let s = match self {
            Self::None => "None".to_string(),
            Self::Class32 => "ELF32".to_string(),
            Self::Class64 => "ELF64".to_string(),
            Self::Num => format!("Unknown!({})", ELF_IDENT_CLASS_NUM),
            Self::Any(v) => format!("Unknown!({})", v),
        };

        write!(f, "{}", s)
    }
}

impl From<u8> for ElfClass {
    fn from(value: u8) -> Self {
        match value {
            ELF_IDENT_CLASS_NONE => Self::None,
            ELF_IDENT_CLASS_32 => Self::Class32,
            ELF_IDENT_CLASS_64 => Self::Class64,
            ELF_IDENT_CLASS_NUM => Self::Num,
            _ => Self::Any(value),
        }
    }
}

impl Default for ElfClass {
    fn default() -> Self {
        Self::None
    }
}
