aliri_braid_impl/
lib.rs

1//! You probably want the [`aliri_braid`] crate, which
2//! has the documentation this crate lacks.
3//!
4//!   [`aliri_braid`]: https://docs.rs/aliri_braid/*/aliri_braid/
5
6#![warn(
7    missing_docs,
8    unused_import_braces,
9    unused_imports,
10    unused_qualifications
11)]
12#![deny(
13    missing_debug_implementations,
14    trivial_casts,
15    trivial_numeric_casts,
16    unused_must_use
17)]
18#![forbid(unsafe_code)]
19
20extern crate proc_macro;
21
22mod codegen;
23
24use codegen::{Params, ParamsRef};
25use proc_macro::TokenStream;
26use syn::parse_macro_input;
27
28/// Constructs a braid
29///
30/// Any attributes assigned to the the struct will be applied to both the owned
31/// and borrowed types, except for doc-comments, with will only be applied to the
32/// owned form.
33///
34/// Available options:
35/// * `ref_name = "RefName"`
36///   * Sets the name of the borrowed type
37/// * `ref_doc = "Alternate doc comment"`
38///   * Overrides the default doc comment for the borrowed type
39/// * `ref_attr = "#[derive(...)]"`
40///   * Provides an attribute to be placed only on the borrowed type
41/// * `owned_attr = "#[derive(...)]"`
42///   * Provides an attribute to be placed only on the owned type
43/// * either `validator [ = "Type" ]` or `normalizer [ = "Type" ]`
44///   * Indicates the type is validated or normalized. If not specified, it is assumed that the
45///     braid implements the relevant trait itself.
46/// * `clone = "impl|omit"` (default: `impl`)
47///   * Changes the automatic derivation of a `Clone` implementation on the owned type.
48/// * `debug = "impl|owned|omit"` (default `impl`)
49///   * Changes how automatic implementations of the `Debug` trait are provided. If `owned`, then
50///     the owned type will generate a `Debug` implementation that will just delegate to the
51///     borrowed implementation. If `omit`, then no implementations of `Debug` will be provided.
52/// * `display = "impl|owned|omit"` (default `impl`)
53///   * Changes how automatic implementations of the `Display` trait are provided. If `owned`, then
54///     the owned type will generate a `Display` implementation that will just delegate to the
55///     borrowed implementation. If `omit`, then no implementations of `Display` will be provided.
56/// * `ord = "impl|owned|omit"` (default `impl`)
57///   * Changes how automatic implementations of the `PartialOrd` and `Ord` traits are provided. If
58///     `owned`, then the owned type will generate implementations that will just delegate to the
59///     borrowed implementations. If `omit`, then no implementations will be provided.
60/// * `serde = "impl|omit"` (default `omit`)
61///   * Adds serialize and deserialize implementations
62/// * `no_expose`
63///   * Functions that expose the internal field type will not be exposed publicly.
64/// * `no_std`
65///   * Generates `no_std`-compatible braid (still requires `alloc`)
66#[proc_macro_attribute]
67pub fn braid(args: TokenStream, input: TokenStream) -> TokenStream {
68    let args = parse_macro_input!(args as Params);
69    let body = parse_macro_input!(input as syn::ItemStruct);
70
71    args.build(body)
72        .map_or_else(syn::Error::into_compile_error, |codegen| codegen.generate())
73        .into()
74}
75
76/// Constructs a ref-only braid
77///
78/// Available options:
79/// * either `validator [ = "Type" ]`
80///   * Indicates the type is validated. If not specified, it is assumed that the braid implements
81///     the relevant trait itself.
82/// * `debug = "impl|omit"` (default `impl`)
83///   * Changes how automatic implementations of the `Debug` trait are provided. If `omit`, then no
84///     implementations of `Debug` will be provided.
85/// * `display = "impl|omit"` (default `impl`)
86///   * Changes how automatic implementations of the `Display` trait are provided. If `omit`, then
87///     no implementations of `Display` will be provided.
88/// * `ord = "impl|omit"` (default `impl`)
89///   * Changes how automatic implementations of the `PartialOrd` and `Ord` traits are provided. If
90///     `omit`, then no implementations will be provided.
91/// * `serde = "impl|omit"` (default `omit`)
92///   * Adds serialize and deserialize implementations
93/// * `no_std`
94///   * Generates a `no_std`-compatible braid that doesn't require `alloc`
95#[proc_macro_attribute]
96pub fn braid_ref(args: TokenStream, input: TokenStream) -> TokenStream {
97    let args = parse_macro_input!(args as ParamsRef);
98    let mut body = parse_macro_input!(input as syn::ItemStruct);
99
100    args.build(&mut body)
101        .unwrap_or_else(syn::Error::into_compile_error)
102        .into()
103}
104
105fn as_validator(validator: &syn::Type) -> proc_macro2::TokenStream {
106    quote::quote! { <#validator as ::aliri_braid::Validator> }
107}
108
109fn as_normalizer(normalizer: &syn::Type) -> proc_macro2::TokenStream {
110    quote::quote! { <#normalizer as ::aliri_braid::Normalizer> }
111}