rkyv_derive/lib.rs
1//! Procedural macros for `rkyv`.
2
3#![deny(
4 rustdoc::broken_intra_doc_links,
5 missing_docs,
6 rustdoc::missing_crate_level_docs
7)]
8
9mod archive;
10mod attributes;
11mod deserialize;
12mod portable;
13mod repr;
14mod serde;
15mod serialize;
16mod util;
17
18extern crate proc_macro;
19
20use syn::{parse_macro_input, DeriveInput};
21
22/// Derives `Portable` for the labeled type.
23#[proc_macro_derive(Portable, attributes(rkyv))]
24pub fn derive_portable(
25 input: proc_macro::TokenStream,
26) -> proc_macro::TokenStream {
27 let mut derive_input = parse_macro_input!(input as DeriveInput);
28 serde::receiver::replace_receiver(&mut derive_input);
29
30 match portable::derive(derive_input) {
31 Ok(result) => result.into(),
32 Err(e) => e.to_compile_error().into(),
33 }
34}
35
36/// Derives `Archive` for the labeled type.
37///
38/// # Attributes
39///
40/// Additional arguments can be specified using `#[rkyv(..)]`, which accepts
41/// the following arguments:
42///
43/// ## Types and fields
44///
45/// - `attr(..)`: Passes along attributes to the generated archived type.
46///
47/// ## Types only
48///
49/// - `derive(..)`: Adds the derives passed as arguments to the generated type.
50/// This is equivalent to `#[rkyv(attr(derive(..)))]`.
51/// - `crate = ..`: Chooses an alternative crate path to import rkyv from.
52/// - `compare(..)`: Implements common comparison operators between the original
53/// and archived types. Supported comparisons are `PartialEq` and `PartialOrd`
54/// (i.e. `#[rkyv(compare(PartialEq, PartialOrd))]`).
55/// - `{archive, serialize, deserialize}_bounds(..)`: Adds additional bounds to
56/// trait implementations. This can be useful for recursive types, where
57/// bounds may need to be omitted to prevent recursive trait impls.
58/// - `bytecheck(..)`: Passed through to the underlying `CheckBytes` derive for
59/// the archived type.
60/// - `as = ..`: Uses the given archived type instead of generating a new one.
61/// This is useful for types which are `Portable` and/or generic over their
62/// parameters.
63/// - `archived = ..`: Changes the name of the generated archived type. By
64/// default, archived types are named "Archived" + `the name of the type`.
65/// - `resolver = ..`: Changes the name of the generated resolver type. By
66/// default, resolver types are named `the name of the type` + "Resolver".
67/// - `remote = ..`: Generate a remote derive for the annotated type instead of
68/// a regular derive.
69///
70/// ## Fields only
71///
72/// - `with = ..`: Applies the given wrapper type to the field.
73/// - `omit_bounds`: Omits trait bounds for the annotated field in the generated
74/// impl.
75/// - `niche` or `niche = ..`: Makes the outer type nichable through the
76/// annotated field using the default niche or a specified one.
77///
78/// # Recursive types
79///
80/// This derive macro automatically adds a type bound `field: Archive` for each
81/// field type. This can cause an overflow while evaluating trait bounds if the
82/// structure eventually references its own type, as the implementation of
83/// `Archive` for a struct depends on each field type implementing it
84/// as well. Adding the attribute `#[rkyv(omit_bounds)]` to a field will
85/// suppress this trait bound and allow recursive structures. This may be too
86/// coarse for some types, in which case additional type bounds may be required
87/// with `{archive, serialize, deserialize}_bounds(..)`.
88///
89/// # Wrappers
90///
91/// Wrappers transparently customize archived types by providing different
92/// implementations of core traits. For example, references cannot be archived,
93/// but the `Inline` wrapper serializes a reference as if it were a field of the
94/// struct. Wrappers can be applied to fields using the `#[rkyv_with = ..]`
95/// attribute.
96#[proc_macro_derive(Archive, attributes(rkyv))]
97pub fn derive_archive(
98 input: proc_macro::TokenStream,
99) -> proc_macro::TokenStream {
100 let mut derive_input = parse_macro_input!(input as DeriveInput);
101 serde::receiver::replace_receiver(&mut derive_input);
102
103 match archive::derive(&mut derive_input) {
104 Ok(result) => result.into(),
105 Err(e) => e.to_compile_error().into(),
106 }
107}
108
109/// Derives `Serialize` for the labeled type.
110///
111/// This macro also supports the `#[rkyv]` attribute. See [`Archive`] for more
112/// information.
113#[proc_macro_derive(Serialize, attributes(rkyv))]
114pub fn derive_serialize(
115 input: proc_macro::TokenStream,
116) -> proc_macro::TokenStream {
117 let mut derive_input = parse_macro_input!(input as DeriveInput);
118 serde::receiver::replace_receiver(&mut derive_input);
119
120 match serialize::derive(derive_input) {
121 Ok(result) => result.into(),
122 Err(e) => e.to_compile_error().into(),
123 }
124}
125
126/// Derives `Deserialize` for the labeled type.
127///
128/// This macro also supports the `#[rkyv]` attribute. See [`Archive`] for more
129/// information.
130#[proc_macro_derive(Deserialize, attributes(rkyv))]
131pub fn derive_deserialize(
132 input: proc_macro::TokenStream,
133) -> proc_macro::TokenStream {
134 let mut derive_input = parse_macro_input!(input as DeriveInput);
135 serde::receiver::replace_receiver(&mut derive_input);
136
137 match deserialize::derive(derive_input) {
138 Ok(result) => result.into(),
139 Err(e) => e.to_compile_error().into(),
140 }
141}