use pyo3::prelude::*;
use pyo3::types::PyType;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PyEnumBase {
Enum,
IntEnum,
StrEnum,
Flag,
IntFlag,
}
impl PyEnumBase {
pub const fn class_name(self) -> &'static str {
match self {
PyEnumBase::Enum => "Enum",
PyEnumBase::IntEnum => "IntEnum",
PyEnumBase::StrEnum => "StrEnum",
PyEnumBase::Flag => "Flag",
PyEnumBase::IntFlag => "IntFlag",
}
}
}
#[derive(Debug, Clone, Copy)]
pub enum VariantLiteral {
Int(i64),
Str(&'static str),
Auto,
}
#[derive(Debug, Clone, Copy)]
pub struct PyEnumSpec {
pub name: &'static str,
pub base: PyEnumBase,
pub variants: &'static [(&'static str, VariantLiteral)],
}
pub trait PyEnum: Sized + Copy + 'static {
const SPEC: PyEnumSpec;
fn py_enum_class(py: Python) -> PyResult<Bound<PyType>>;
fn to_py_member<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>>;
fn from_py_member(obj: &Bound<PyAny>) -> PyResult<Self>;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn class_name_matches_python_enum_module_attrs() {
assert_eq!(PyEnumBase::Enum.class_name(), "Enum");
assert_eq!(PyEnumBase::IntEnum.class_name(), "IntEnum");
assert_eq!(PyEnumBase::StrEnum.class_name(), "StrEnum");
assert_eq!(PyEnumBase::Flag.class_name(), "Flag");
assert_eq!(PyEnumBase::IntFlag.class_name(), "IntFlag");
}
}