macro_rules! py_wrap_union_enum {
(@from $name: ident, $rs_enum: ident, $variant_name: ident, $variant: ident $(=> $convert: ty)+) => { ... };
(@from $name: ident, $rs_enum: ident, $variant_name: ident, $variant: ident) => { ... };
(@is_variant $self: ident, $rs_enum: ident, $variant: ident ($(=> $_convert: ty)+)) => { ... };
(@is_variant $self: ident, $rs_enum: ident, $variant: ident) => { ... };
(
$(#[$meta: meta])*
$name: ident($rs_inner: ident) $(as $py_class: literal)? {
$($variant_name: ident: $variant: ident $($(=> $convert: ty)+)?),+
}
) => { ... };
}Expand description
Create a newtype wrapper for a Rust enum with unique 1-tuple variants.
§Implements
- Conversion between the wrapper and the inner enum
- A Python constructor that creates a new instance from one of the Python variants.
- A Python function
inner()that directly returns the Python version of the variant discriminant (i.e.DiscriminantinEnum::Variant(Discriminant)). - Python conversion functions:
from_x: Like the constructor, but for a specific variantx.is_x: ReturnsTrueif the enum is variantx.as_x: Returns the discriminant if the enum is variantx, otherwiseNone.to_x: Returns the discriminant if the enum is variantx, otherwise raisesValueError.
§Example
use rigetti_pyo3::py_wrap_union_enum;
use rigetti_pyo3::pyo3::prelude::*;
use rigetti_pyo3::pyo3::types::*;
use std::collections::HashSet;
#[derive(Clone)]
pub enum TestEnum {
Unit,
String(String),
Integer(i32),
UInteger(u32),
List(Vec<HashSet<String>>),
Mapping(std::collections::HashMap<String, String>),
}
py_wrap_union_enum! {
PyTestEnum(TestEnum) as "TestEnum" {
// Syntax is (1): (2) [=> (3)] [=> (4)] [...], where:
// 1: The name used in generated methods
// 2: The name of the Rust enum variant
// 3: The (Python) type the inner item must convert to (if it has associated data)
// 4: The (Python) type the type from (3) must convert to, etc.
unit: Unit,
// Read as "give the name `string` to variant `String`, which must convert (from
// a `String`) to a `String` and then to a `Py<PyString>`."
//
// That is, `string` is used to generate methods `is_string`, `from_string`, etc.;
// the first `String` is the name of the variant, not the type (which is elided);
// the second `String` is the type to convert the elided type into, and `Py<String>` is
// the final type to convert into.
//
// This specifies an unnecessary conversion from String => String to illustrate
// conversion chaining.
string: String => String => Py<PyString>,
int: Integer => Py<PyInt>,
uint: UInteger => Py<PyInt>,
list: List => Py<PyList>,
// Alternatively, in the case of `Vec<T>` where `T` does not have conversion to `PyAny`.
// list: List => Vec<Py<PySet>> => Py<PyList>,
// Generates `from_dict`, `is_dict`, `as_dict`, `to_dict`
dict: Mapping => Py<PyDict>
}
}