udf_macros/lib.rs
1#![warn(
2 clippy::pedantic,
3 clippy::nursery,
4 clippy::str_to_string,
5 clippy::missing_inline_in_public_items
6)]
7// Pedantic config
8#![allow(
9 clippy::missing_const_for_fn,
10 clippy::missing_panics_doc,
11 clippy::must_use_candidate,
12 clippy::cast_possible_truncation
13)]
14
15mod register;
16mod types;
17
18use proc_macro::TokenStream;
19
20macro_rules! match_variant {
21 ($variant:path) => {
22 |x| {
23 if let $variant(value) = x {
24 Some(value)
25 } else {
26 None
27 }
28 }
29 };
30}
31
32pub(crate) use match_variant;
33
34/// # Register exposed function names required for a UDF
35///
36/// This macro is applied to an `impl BasicUdf` block (and an `AggregateUdf`
37/// block, if applicable) and exposed the C-callable functions that
38/// `MariaDB`/`MySQL` expect.
39///
40/// Usage:
41///
42/// ```ignore
43/// #[register]
44/// impl BasicUdf for MyStruct {
45/// ...
46/// }
47///
48/// #[register]
49/// impl AggregateUdf for MyStruct {
50/// ...
51/// }
52/// ```
53///
54/// Its process is as follows:
55///
56/// - Convert the implemented struct's name to snake case to create the function
57/// name (unless a name is specified)
58/// - Obtain the return type from the `Returns` type in `BasicUdf`
59/// - Create functions `fn_name`, `fn_name_init`, and `fn_name_deinit` with
60/// correct signatures and interfaces
61/// - If applied on an `impl AggregateUdf` block, create `fn_name_clear` and
62/// `fn_name_add`. `fn_name_remove` is also included if it is redefined
63///
64/// # Arguments
65///
66/// - `#[udf::register(name = "new_name")]` will specify a name for your SQL
67/// function. If this is not specified, your struct name will be converted to
68/// snake case and used (e.g. `AddAllNumbers` would become `add_all_numbers`
69/// by default).
70/// - `#[udf::register(alias = "alias")]` will specify an alias for this function.
71/// More than one alias can be specified, and it can be combined with a `name` attribute.
72///
73/// **IMPORTANT**: if using aggregate UDFs, the exact same renaming must be applied to
74/// both the `impl BasicUdf` and the `impl AggregateUdf` blocks! If this is not followed,
75/// your function will not act as an aggregate (there may also be a compile error).
76#[proc_macro_attribute]
77pub fn register(args: TokenStream, item: TokenStream) -> TokenStream {
78 // Keep this file clean by keeping the dirty work in entry
79 register::register(&args, item)
80}