af_move_type_derive/
lib.rs

1//! Derive macros for traits defined in `af-move-type`.
2
3mod move_struct;
4
5use move_struct::impl_move_struct;
6use proc_macro::TokenStream;
7
8/// Derives `af_move_type` trait implementations for a type representing a Move struct.
9///
10/// Creates the `_TypeTag` struct related to the struct being annotated, with conversion traits
11/// between the former and the dynamic `StructTag` type, with errors like 'expected module to be x'
12/// or 'expected struct name to be y', if we know those things at compile time (see the
13/// [Attributes](#attributes) section for configurations around those checks).
14///
15/// # Attributes
16///
17/// - `#[move_(crate = ...)]`: sets the path of the `af_move_type` crate, which can be useful if
18///   using this inside other macros.
19/// - `#[move_(address = "...")]`: sets a static package address for the derived `MoveTypeTag`.
20///   Deserialization of the latter will fail if the package addresses do not match.
21/// - `#[move_(module = "...")]`: sets a static module name for the derived `MoveTypeTag`.
22///   Deserialization of the latter will fail if the module names do not match.
23/// - `#[move_(nameless)]`: make the struct name dynamic for the derived `MoveTypeTag`. Upon the
24///   deserializing the latter, any Move struct name will be accepted. Otherwise, deserialization
25///   will fail if the incoming struct name is not equal to the Rust struct's name.
26///
27/// # `MoveTypeTag` derivation
28///
29/// For a struct `Name<T: MoveType>`, the macro will create a `NameTypeTag` struct with fields:
30/// - `address: Address`, unless the `#[move_(address = "...")]` attribute is present
31/// - `module: Identifier`, unless the `#[move_(module = "...")]` attribute is present
32/// - `name: Identifier` only if the `#[move_(nameless)]` attribute is present
33/// - `t: <T as MoveType>::TypeTag`
34///
35/// The macro will also create custom `Into<StructTag>`, `Into<TypeTag>`, `TryFrom<StructTag>`,
36/// `TryFrom<TypeTag>`, `Display` and `FromStr` impls for `NameTypeTag`.
37///
38/// # Derived traits
39///
40/// - `af_move_type::MoveStruct`
41/// - `af_move_type::StaticAddress` if `#[move_(address = "...")]` is specified
42/// - `af_move_type::StaticModule` if `#[move_(module = "...")]` is specified
43/// - `af_move_type::StaticName` if `#[move_(nameless)]` was **not** specified
44/// - `af_move_type::StaticTypeParams`
45/// - `af_move_type::StaticStructTag` if applicable
46/// - `af_move_type::StaticTypeTag` if applicable
47///
48#[proc_macro_derive(MoveStruct, attributes(move_))]
49pub fn move_struct_derive_macro(item: TokenStream) -> TokenStream {
50    impl_move_struct(item.into())
51        .unwrap_or_else(syn::Error::into_compile_error)
52        .into()
53}