[−]Derive Macro vessels::Kind
#[derive(Kind)] { // Attributes available to this derive: #[kind] }
Generates an implementation of Kind
for a struct or enum.
This macro has a number of modes of operation. First, it may be used in a fashion equivalent to the manner of operation of standard library derive macros.
use vessels::Kind; #[derive(Kind)] struct Person<T> { name: T, say_hello: Box<dyn Fn() -> T + Sync + Send>, }
This will generate an implementation of Kind
for the annotated type given an extant implementation of Kind
for each field of that type. There is further nuance to this mode of operation, but to explain it is best to first
demonstrate the other primary manner of operation.
use vessels::{Kind, kind::using}; use serde::{Serialize, Deserialize} #[derive(Serialize, Deserialize)] struct NotKind; #[derive(Serialize, Deserialize, Kind)] #[kind(using::Serde)] struct Person { name: String, data: NotKind, }
This will generate an implementation of Kind
for the annotated type despite NotKind
lacking a valid implementation.
The types, provided in vessels::kind::using
, that provide AsKind
trait implementations, allow for the use of an
alternative bijection for structs and enums that implement some certain traits permitting such a thing. To finally attend
to the additional mode of operation mentioned earlier, these #[kind()]
annotations may be used with the initially discussed
syntax.
#[derive(Kind)] struct Person { name: String, #[kind(using::Serde)] data: NotKind, }
Annotating a field of a struct or enum with #[kind()]
, if the type provided in the attribute annotation is a valid AsKind
for the type of that field, will cause the overarching derivation to use that type as a wrapper to produce a valid Kind
bijection.
All of the described behavior also functions for arbitrary generic parameters and when used in enums with both named and unnamed fields.
#[derive(Kind)] enum Entity<T: Kind> { Person { name: String, #[kind(using::Serde)] data: NotKind, }, UnnamedFields(#[kind(using::Serde)] NotKind, T) }