Attribute Macro rs_class
#[rs_class]Expand description
Define an object type in Rust from its object struct, as Python’s
py_class does: the type registers its key with the reflection of every
field, so that C++ structural equality and hashing, repr, deep copy and
Python see the fields.
use tvm_ffi::{def_object_ref, rs_class};
/// A pair of values under a `Base`.
#[rs_class("my_ext.Pair", final)]
pub struct PairObj {
base: BaseObj,
pub first: tvm_ffi::String,
pub second: tvm_ffi::String,
#[reflect(seq_hash_ignore)]
pub note: tvm_ffi::String,
}
def_object_ref!(pub Pair, Base, PairObj);
let pair = Pair::from(PairObj::new(BaseObj::new(/* ... */), "a", "b", ""));
let base = Base::from(pair);The first field, base, is the parent’s object, as the base class of a C++
object is: base: Object for a type under ffi.Object. The parent’s object
must implement ShallowCopy and UnsafeInit, as rs_class types and
non-final C++ types bound by tvm-ffi-stubgen do. Every other field is
reflected; #[reflect(writable, seq_hash_ignore, ...)] gives a field the
FieldFlags of those names, and name and doc as for
derive(Object). The macro adds to the struct:
#[repr(C)]andDerefto the parent’s object, soobj.fieldreads the fields of both.PairObj::new(base, ...), which builds the object from the parent’s object and the fields in order: a scalar (bool, an integer or a float) as its own type, so that a literal infers as it, and any other field from anything that converts into it, as thenewof a type bound bytvm-ffi-stubgentakes them.
def_object_ref! defines the reference to it and its conversion into the
reference to its parent.
After the type key:
final,s_eq_hash_kind = "TreeNode",child_slots = N,child_slots_can_overflow = boolandreflection = patharederive(Object)’s#[type_final],#[type_s_eq_hash_kind],#[type_child_slots],#[type_child_slots_can_overflow]and#[type_reflection].crate = pathis where the generated code finds tvm-ffi (crate = ::my_lib::tvm_ffi), for a crate that depends on it only through a re-export; by defaulttvm_ffi.
The type is a derive(Object) type with #[type_register]: it registers on
its first type_index(), with the fields, the methods,
__ffi_shallow_copy__ and __ffi_type_final__, and a creator that makes
the object with every field undefined for reflection to set, as C++ makes one
with UnsafeInit, from which it registers __ffi_new__ and, unless the
methods define it, __ffi_init__; the macro implements UnsafeInit for
the object. A field’s type must implement AnyCompatible and Clone; an
init_off field’s type must take all-zero bytes as a value, as
__ffi_init__ leaves the field so.