use crate::api_def::Function;
use crate::api_def::Generic;
use crate::api_def::NamedType;
pub struct Enum {
pub name: &'static str,
pub generics: &'static [Generic],
pub variants: &'static [NamedType],
pub functions: &'static [Function],
}
#[cfg(test)]
mod tests {
use crate::api_def::Type;
use crate::api_def::TypeDefinition;
#[test]
fn enum_definition() {
#[derive(agdb::TypeDefImpl)]
enum SomeEnum {}
let enum_def = SomeEnum::type_def();
if let Type::Enum(e) = enum_def {
assert_eq!(e.name, "SomeEnum");
assert_eq!(e.generics.len(), 0);
assert_eq!(e.variants.len(), 0);
} else {
panic!("Expected Type::Enum");
}
}
#[test]
fn enum_definition_with_variants() {
#[derive(agdb::TypeDefImpl)]
#[allow(dead_code)]
enum SimpleEnum {
A,
B,
C,
}
let enum_def = SimpleEnum::type_def();
if let Type::Enum(e) = enum_def {
assert_eq!(e.variants.len(), 3);
assert_eq!(e.variants[0].name, "A");
assert_eq!(e.variants[1].name, "B");
assert_eq!(e.variants[2].name, "C");
} else {
panic!("Expected Type::Enum");
}
}
#[test]
fn enum_definition_with_generics() {
#[derive(agdb::TypeDefImpl)]
#[allow(dead_code)]
enum GenericEnum<T, U> {
Variant1 { field1: T },
Variant2 { field2: U },
}
let enum_def = GenericEnum::<i32, f64>::type_def();
if let Type::Enum(e) = enum_def {
assert_eq!(e.generics.len(), 2);
assert_eq!(e.generics[0].name, "T");
assert_eq!(e.generics[1].name, "U");
assert_eq!(e.variants.len(), 2);
assert_eq!(e.variants[0].name, "Variant1");
if let Type::Struct(s) = (e.variants[0].ty.unwrap())() {
assert_eq!(s.fields.len(), 1);
assert_eq!(s.fields[0].name, "field1");
} else {
panic!("Expected Variant1 field type to be Struct");
}
assert_eq!(e.variants[1].name, "Variant2");
if let Type::Struct(s) = (e.variants[1].ty.unwrap())() {
assert_eq!(s.fields.len(), 1);
assert_eq!(s.fields[0].name, "field2");
} else {
panic!("Expected Variant2 field type to be Struct");
}
} else {
panic!("Expected Type::Enum");
}
}
#[test]
fn enum_definition_variant_of_another_type() {
#[derive(agdb::TypeDef)]
struct OtherType;
#[agdb::impl_def()]
#[allow(dead_code)]
impl OtherType {
fn foo() {}
}
#[derive(agdb::TypeDefImpl)]
#[allow(dead_code)]
enum OtherTypeEnum {
TupleVariant(OtherType),
}
let enum_def = OtherTypeEnum::type_def();
if let Type::Enum(e) = enum_def {
assert_eq!(e.variants.len(), 1);
assert_eq!(e.variants[0].name, "TupleVariant");
if let Type::Tuple(t) = (e.variants[0].ty.unwrap())() {
if let Type::Struct(s) = (t.fields[0])() {
assert_eq!(s.name, "OtherType");
s.functions
.iter()
.find(|f| f.name == "foo")
.expect("Expected function foo");
} else {
panic!("Expected TupleVariant field type to be OtherType Struct");
}
} else {
panic!("Expected UnitVariant type to be None");
}
} else {
panic!("Expected Type::Enum");
}
}
}