Skip to main content

fieldmask_derive/
lib.rs

1mod derive;
2mod func;
3
4use derive::{derive_maskable_impl, derive_option_maskable_impl, derive_self_maskable_impl};
5use func::maskable_atomic_impl;
6use proc_macro::TokenStream;
7
8/// Derive `Maskable` for the type.
9///
10/// The type must be one of the following types:
11/// - A unit-like enum.
12/// - An enum where each variant has exactly one unnamed associated field. The associated field must
13///   implement `Maskable`.
14/// - A struct with named fields, where the type of each field must implement `Maskable`.
15#[proc_macro_derive(Maskable, attributes(fieldmask))]
16pub fn derive_maskable(input: TokenStream) -> TokenStream {
17    derive_maskable_impl(input)
18}
19
20/// Derive `OptionMaskable` for the type.
21///
22/// The type must be one of the following types:
23/// - A unit-like enum.
24/// - An enum where each variant has exactly one unnamed associated field. The associated field must
25///   implement `SelfMaskable` and `Default`.
26/// - A struct that implements `Default`, `PartialEq` and `SelfMaskable`.
27///
28/// # Caveats:
29/// When deriving `OptionMaskable` for a unit enum that implements `Default`, you should consider
30/// adding attribute `#[fieldmask(normalize_some_default)]` to the enum. Without this,
31/// `Some(MyUnitEnum::default())` will NOT be normalized to `None` when `ProjectOption::normalize`
32/// is set to true.
33/// Alternatively, you can implement `OptionMaskable` and `SelfMaskable` on the unit enum using the
34/// `maskable_atomic!` macro.
35#[proc_macro_derive(OptionMaskable, attributes(fieldmask))]
36pub fn derive_option_maskable(input: TokenStream) -> TokenStream {
37    derive_option_maskable_impl(input)
38}
39
40/// Derive `SelfMaskable` for the type.
41///
42/// The type must be one of the following types:
43/// - A unit-like enum that implements `Default` and `PartialEqual`.
44/// - A struct with named fields, where the type of each field must implement `Default`,
45///   `PartialEqual`, and `SelfMaskable`.
46#[proc_macro_derive(SelfMaskable, attributes(fieldmask))]
47pub fn derive_self_maskable(input: TokenStream) -> TokenStream {
48    derive_self_maskable_impl(input)
49}
50
51/// Treat the type as an atomic value and Implement `Maskable`, `OptionMaskable`, `SelfMaskable`
52/// for the type.
53///
54/// You can override the default implementation of `update_as_field` and `merge` if needed.
55///
56/// ### Example:
57/// ```ignore
58/// maskable_atomic!(impl bool {});
59///
60/// maskable_atomic!(
61///     impl<T> Vec<T> {
62///         // Omit this if you don't want to override the default implementation.
63///         fn update_as_field(&mut self, source: Self, _mask: &Self::Mask, options: &UpdateOptions) {
64///             self.merge(source, options);
65///         }
66///
67///         // Omit this if you don't want to override the default implementation.
68///         fn merge(&mut self, source: Self, options: &UpdateOptions) {
69///             if options.replace_repeated {
70///                 *self = source;
71///                 return;
72///             }
73///
74///             self.extend(source);
75///         }
76///     }
77/// );
78/// ```
79#[proc_macro]
80pub fn maskable_atomic(input: TokenStream) -> TokenStream {
81    maskable_atomic_impl(input)
82}