Attribute Macro zerovec::make_varule
source · #[make_varule]
Expand description
Generate a corresponding VarULE
type and the relevant EncodeAsVarULE
/zerofrom::ZeroFrom
implementations for this type
This can be attached to structs containing only AsULE
types with the last fields being
Cow<'a, str>
, ZeroSlice
, or VarZeroSlice
. If there is more than one such field, it will be represented
using MultiFieldsULE
and getters will be generated. Other VarULE fields will be detected if they are
tagged with #[zerovec::varule(NameOfVarULETy)]
.
The type must be PartialEq
and Eq
.
EncodeAsVarULE
and zerofrom::ZeroFrom
are useful for avoiding the need to deal with
the VarULE
type directly. In particular, it is recommended to use zerofrom::ZeroFrom
to convert the VarULE
type back to this type in a cheap, zero-copy way (see the example below
for more details).
#[make_varule]
will automatically derive the following traits on the VarULE
type:
Ord
andPartialOrd
ZeroMapKV
To disable one of the automatic derives, use #[zerovec::skip_derive(...)]
like so: #[zerovec::skip_derive(ZeroMapKV)]
.
Ord
and PartialOrd
are implemented as a unit and can only be disabled as a group with #[zerovec::skip_derive(Ord)]
.
The following traits are available to derive, but not automatic:
To enable one of these additional derives, use #[zerovec::derive(...)]
like so: #[zerovec::derive(Debug)]
.
In most cases these derives will defer to the impl of the same trait on the current type, so such impls must exist.
This implementation will also by default autogenerate Ord
and PartialOrd
on the VarULE
type based on
the implementation on Self
. You can opt out of this with #[zerovec::skip_derive(Ord)]
Note that this implementation will autogenerate EncodeAsVarULE
impls for both Self
and &Self
for convenience. This allows for a little more flexibility encoding slices.
§Example
use std::borrow::Cow;
use zerofrom::ZeroFrom;
use zerovec::ule::encode_varule_to_box;
use zerovec::{VarZeroVec, ZeroMap, ZeroVec};
// custom fixed-size ULE type for ZeroVec
#[zerovec::make_ule(DateULE)]
#[derive(Copy, Clone, PartialEq, Eq, Ord, PartialOrd, serde::Serialize, serde::Deserialize)]
struct Date {
y: u64,
m: u8,
d: u8,
}
// custom variable sized VarULE type for VarZeroVec
#[zerovec::make_varule(PersonULE)]
#[zerovec::derive(Serialize, Deserialize)]
#[derive(Clone, PartialEq, Eq, Ord, PartialOrd, serde::Serialize, serde::Deserialize)]
struct Person<'a> {
birthday: Date,
favorite_character: char,
#[serde(borrow)]
name: Cow<'a, str>,
}
#[derive(serde::Serialize, serde::Deserialize)]
struct Data<'a> {
// note: VarZeroVec always must reference the ULE type directly
#[serde(borrow)]
important_people: VarZeroVec<'a, PersonULE>,
}
let person1 = Person {
birthday: Date {
y: 1990,
m: 9,
d: 7,
},
favorite_character: 'π',
name: Cow::from("Kate"),
};
let person2 = Person {
birthday: Date {
y: 1960,
m: 5,
d: 25,
},
favorite_character: '冇',
name: Cow::from("Jesse"),
};
let important_people = VarZeroVec::from(&[person1, person2]);
let data = Data { important_people };
let bincode_bytes = bincode::serialize(&data).expect("Serialization should be successful");
// Will deserialize without allocations
let deserialized: Data =
bincode::deserialize(&bincode_bytes).expect("Deserialization should be successful");
assert_eq!(&deserialized.important_people.get(1).unwrap().name, "Jesse");
assert_eq!(&deserialized.important_people.get(0).unwrap().name, "Kate");
// Since VarZeroVec produces PersonULE types, it's convenient to use ZeroFrom
// to recoup Person values in a zero-copy way
let person_converted: Person =
ZeroFrom::zero_from(deserialized.important_people.get(1).unwrap());
assert_eq!(person_converted.name, "Jesse");
assert_eq!(person_converted.birthday.y, 1960);
Full docs for this proc macro can be found on the zerovec
crate.