datafusion_functions_window/macros.rs
1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18//! Convenience macros for defining a user-defined window function
19//! and associated expression API (fluent style).
20//!
21//! See [`define_udwf_and_expr!`] for usage examples.
22//!
23//! [`define_udwf_and_expr!`]: crate::define_udwf_and_expr!
24
25/// Lazily initializes a user-defined window function exactly once
26/// when called concurrently. Repeated calls return a reference to the
27/// same instance.
28///
29/// # Parameters
30///
31/// * `$UDWF`: The struct which defines the [`Signature`](datafusion_expr::Signature)
32/// of the user-defined window function.
33/// * `$OUT_FN_NAME`: The basename to generate a unique function name like
34/// `$OUT_FN_NAME_udwf`.
35/// * `$DOC`: Doc comments for UDWF.
36/// * (optional) `$CTOR`: Pass a custom constructor. When omitted it
37/// automatically resolves to `$UDWF::default()`.
38///
39/// # Example
40///
41/// ```
42/// # use std::any::Any;
43/// # use datafusion_common::arrow::datatypes::{DataType, Field};
44/// # use datafusion_expr::{PartitionEvaluator, Signature, Volatility, WindowUDFImpl};
45/// #
46/// # use datafusion_functions_window_common::field::WindowUDFFieldArgs;
47/// # use datafusion_functions_window::get_or_init_udwf;
48/// # use datafusion_functions_window_common::partition::PartitionEvaluatorArgs;
49/// #
50/// /// Defines the `simple_udwf()` user-defined window function.
51/// get_or_init_udwf!(
52/// SimpleUDWF,
53/// simple,
54/// "Simple user-defined window function doc comment."
55/// );
56/// #
57/// # assert_eq!(simple_udwf().name(), "simple_user_defined_window_function");
58/// #
59/// # #[derive(Debug)]
60/// # struct SimpleUDWF {
61/// # signature: Signature,
62/// # }
63/// #
64/// # impl Default for SimpleUDWF {
65/// # fn default() -> Self {
66/// # Self {
67/// # signature: Signature::any(0, Volatility::Immutable),
68/// # }
69/// # }
70/// # }
71/// #
72/// # impl WindowUDFImpl for SimpleUDWF {
73/// # fn as_any(&self) -> &dyn Any {
74/// # self
75/// # }
76/// # fn name(&self) -> &str {
77/// # "simple_user_defined_window_function"
78/// # }
79/// # fn signature(&self) -> &Signature {
80/// # &self.signature
81/// # }
82/// # fn partition_evaluator(
83/// # &self,
84/// # _partition_evaluator_args: PartitionEvaluatorArgs,
85/// # ) -> datafusion_common::Result<Box<dyn PartitionEvaluator>> {
86/// # unimplemented!()
87/// # }
88/// # fn field(&self, field_args: WindowUDFFieldArgs) -> datafusion_common::Result<Field> {
89/// # Ok(Field::new(field_args.name(), DataType::Int64, false))
90/// # }
91/// # }
92/// #
93/// ```
94#[macro_export]
95macro_rules! get_or_init_udwf {
96 ($UDWF:ident, $OUT_FN_NAME:ident, $DOC:expr) => {
97 get_or_init_udwf!($UDWF, $OUT_FN_NAME, $DOC, $UDWF::default);
98 };
99
100 ($UDWF:ident, $OUT_FN_NAME:ident, $DOC:expr, $CTOR:path) => {
101 paste::paste! {
102 #[doc = concat!(" Returns a [`WindowUDF`](datafusion_expr::WindowUDF) for [`", stringify!($OUT_FN_NAME), "`].")]
103 #[doc = ""]
104 #[doc = concat!(" ", $DOC)]
105 pub fn [<$OUT_FN_NAME _udwf>]() -> std::sync::Arc<datafusion_expr::WindowUDF> {
106 // Singleton instance of UDWF, ensures it is only created once.
107 static INSTANCE: std::sync::LazyLock<std::sync::Arc<datafusion_expr::WindowUDF>> =
108 std::sync::LazyLock::new(|| {
109 std::sync::Arc::new(datafusion_expr::WindowUDF::from($CTOR()))
110 });
111 std::sync::Arc::clone(&INSTANCE)
112 }
113 }
114 };
115}
116
117/// Create a [`WindowFunction`] expression that exposes a fluent API
118/// which you can use to build more complex expressions.
119///
120/// [`WindowFunction`]: datafusion_expr::Expr::WindowFunction
121///
122/// # Parameters
123///
124/// * `$UDWF`: The struct which defines the [`Signature`] of the
125/// user-defined window function.
126/// * `$OUT_FN_NAME`: The basename to generate a unique function name like
127/// `$OUT_FN_NAME_udwf`.
128/// * `$DOC`: Doc comments for UDWF.
129/// * (optional) `[$($PARAM:ident),+]`: An array of 1 or more parameters
130/// for the generated function. The type of parameters is [`Expr`].
131/// When omitted this creates a function with zero parameters.
132///
133/// [`Signature`]: datafusion_expr::Signature
134/// [`Expr`]: datafusion_expr::Expr
135///
136/// # Example
137///
138/// 1. With Zero Parameters
139/// ```
140/// # use std::any::Any;
141/// # use datafusion_common::arrow::datatypes::{DataType, Field};
142/// # use datafusion_expr::{PartitionEvaluator, Signature, Volatility, WindowUDFImpl};
143/// # use datafusion_functions_window::{create_udwf_expr, get_or_init_udwf};
144/// # use datafusion_functions_window_common::field::WindowUDFFieldArgs;
145/// # use datafusion_functions_window_common::partition::PartitionEvaluatorArgs;
146///
147/// # get_or_init_udwf!(
148/// # RowNumber,
149/// # row_number,
150/// # "Returns a unique row number for each row in window partition beginning at 1."
151/// # );
152/// /// Creates `row_number()` API which has zero parameters:
153/// ///
154/// /// ```
155/// /// /// Returns a unique row number for each row in window partition
156/// /// /// beginning at 1.
157/// /// pub fn row_number() -> datafusion_expr::Expr {
158/// /// row_number_udwf().call(vec![])
159/// /// }
160/// /// ```
161/// create_udwf_expr!(
162/// RowNumber,
163/// row_number,
164/// "Returns a unique row number for each row in window partition beginning at 1."
165/// );
166/// #
167/// # assert_eq!(
168/// # row_number().name_for_alias().unwrap(),
169/// # "row_number() ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING"
170/// # );
171/// #
172/// # #[derive(Debug)]
173/// # struct RowNumber {
174/// # signature: Signature,
175/// # }
176/// # impl Default for RowNumber {
177/// # fn default() -> Self {
178/// # Self {
179/// # signature: Signature::any(0, Volatility::Immutable),
180/// # }
181/// # }
182/// # }
183/// # impl WindowUDFImpl for RowNumber {
184/// # fn as_any(&self) -> &dyn Any {
185/// # self
186/// # }
187/// # fn name(&self) -> &str {
188/// # "row_number"
189/// # }
190/// # fn signature(&self) -> &Signature {
191/// # &self.signature
192/// # }
193/// # fn partition_evaluator(
194/// # &self,
195/// # _partition_evaluator_args: PartitionEvaluatorArgs,
196/// # ) -> datafusion_common::Result<Box<dyn PartitionEvaluator>> {
197/// # unimplemented!()
198/// # }
199/// # fn field(&self, field_args: WindowUDFFieldArgs) -> datafusion_common::Result<Field> {
200/// # Ok(Field::new(field_args.name(), DataType::UInt64, false))
201/// # }
202/// # }
203/// ```
204///
205/// 2. With Multiple Parameters
206/// ```
207/// # use std::any::Any;
208/// #
209/// # use datafusion_expr::{
210/// # PartitionEvaluator, Signature, TypeSignature, Volatility, WindowUDFImpl,
211/// # };
212/// #
213/// # use datafusion_functions_window::{create_udwf_expr, get_or_init_udwf};
214/// # use datafusion_functions_window_common::field::WindowUDFFieldArgs;
215/// #
216/// # use datafusion_common::arrow::datatypes::Field;
217/// # use datafusion_common::ScalarValue;
218/// # use datafusion_expr::{col, lit};
219/// # use datafusion_functions_window_common::partition::PartitionEvaluatorArgs;
220/// #
221/// # get_or_init_udwf!(Lead, lead, "user-defined window function");
222/// #
223/// /// Creates `lead(expr, offset, default)` with 3 parameters:
224/// ///
225/// /// ```
226/// /// /// Returns a value evaluated at the row that is offset rows
227/// /// /// after the current row within the partition.
228/// /// pub fn lead(
229/// /// expr: datafusion_expr::Expr,
230/// /// offset: datafusion_expr::Expr,
231/// /// default: datafusion_expr::Expr,
232/// /// ) -> datafusion_expr::Expr {
233/// /// lead_udwf().call(vec![expr, offset, default])
234/// /// }
235/// /// ```
236/// create_udwf_expr!(
237/// Lead,
238/// lead,
239/// [expr, offset, default],
240/// "Returns a value evaluated at the row that is offset rows after the current row within the partition."
241/// );
242/// #
243/// # assert_eq!(
244/// # lead(col("a"), lit(1i64), lit(ScalarValue::Null))
245/// # .name_for_alias()
246/// # .unwrap(),
247/// # "lead(a,Int64(1),NULL) ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING"
248/// # );
249/// #
250/// # #[derive(Debug)]
251/// # struct Lead {
252/// # signature: Signature,
253/// # }
254/// #
255/// # impl Default for Lead {
256/// # fn default() -> Self {
257/// # Self {
258/// # signature: Signature::one_of(
259/// # vec![
260/// # TypeSignature::Any(1),
261/// # TypeSignature::Any(2),
262/// # TypeSignature::Any(3),
263/// # ],
264/// # Volatility::Immutable,
265/// # ),
266/// # }
267/// # }
268/// # }
269/// #
270/// # impl WindowUDFImpl for Lead {
271/// # fn as_any(&self) -> &dyn Any {
272/// # self
273/// # }
274/// # fn name(&self) -> &str {
275/// # "lead"
276/// # }
277/// # fn signature(&self) -> &Signature {
278/// # &self.signature
279/// # }
280/// # fn partition_evaluator(
281/// # &self,
282/// # partition_evaluator_args: PartitionEvaluatorArgs,
283/// # ) -> datafusion_common::Result<Box<dyn PartitionEvaluator>> {
284/// # unimplemented!()
285/// # }
286/// # fn field(&self, field_args: WindowUDFFieldArgs) -> datafusion_common::Result<Field> {
287/// # Ok(Field::new(
288/// # field_args.name(),
289/// # field_args.get_input_type(0).unwrap(),
290/// # false,
291/// # ))
292/// # }
293/// # }
294/// ```
295#[macro_export]
296macro_rules! create_udwf_expr {
297 // zero arguments
298 ($UDWF:ident, $OUT_FN_NAME:ident, $DOC:expr) => {
299 paste::paste! {
300 #[doc = " Create a [`WindowFunction`](datafusion_expr::Expr::WindowFunction) expression for"]
301 #[doc = concat!(" `", stringify!($UDWF), "` user-defined window function.")]
302 #[doc = ""]
303 #[doc = concat!(" ", $DOC)]
304 pub fn $OUT_FN_NAME() -> datafusion_expr::Expr {
305 [<$OUT_FN_NAME _udwf>]().call(vec![])
306 }
307 }
308 };
309
310 // 1 or more arguments
311 ($UDWF:ident, $OUT_FN_NAME:ident, [$($PARAM:ident),+], $DOC:expr) => {
312 paste::paste! {
313 #[doc = " Create a [`WindowFunction`](datafusion_expr::Expr::WindowFunction) expression for"]
314 #[doc = concat!(" `", stringify!($UDWF), "` user-defined window function.")]
315 #[doc = ""]
316 #[doc = concat!(" ", $DOC)]
317 pub fn $OUT_FN_NAME(
318 $($PARAM: datafusion_expr::Expr),+
319 ) -> datafusion_expr::Expr {
320 [<$OUT_FN_NAME _udwf>]()
321 .call(vec![$($PARAM),+])
322 }
323 }
324 };
325}
326
327/// Defines a user-defined window function.
328///
329/// Combines [`get_or_init_udwf!`] and [`create_udwf_expr!`] into a
330/// single macro for convenience.
331///
332/// # Arguments
333///
334/// * `$UDWF`: The struct which defines the [`Signature`] of the
335/// user-defined window function.
336/// * `$OUT_FN_NAME`: The basename to generate a unique function name like
337/// `$OUT_FN_NAME_udwf`.
338/// * (optional) `[$($PARAM:ident),+]`: An array of 1 or more parameters
339/// for the generated function. The type of parameters is [`Expr`].
340/// When omitted this creates a function with zero parameters.
341/// * `$DOC`: Doc comments for UDWF.
342/// * (optional) `$CTOR`: Pass a custom constructor. When omitted it
343/// automatically resolves to `$UDWF::default()`.
344///
345/// [`Signature`]: datafusion_expr::Signature
346/// [`Expr`]: datafusion_expr::Expr
347///
348/// # Usage
349///
350/// ## Expression API With Zero parameters
351/// 1. Uses default constructor for UDWF.
352///
353/// ```
354/// # use std::any::Any;
355/// # use datafusion_common::arrow::datatypes::{DataType, Field};
356/// # use datafusion_expr::{PartitionEvaluator, Signature, Volatility, WindowUDFImpl};
357/// #
358/// # use datafusion_functions_window_common::field::WindowUDFFieldArgs;
359/// # use datafusion_functions_window::{define_udwf_and_expr, get_or_init_udwf, create_udwf_expr};
360/// # use datafusion_functions_window_common::partition::PartitionEvaluatorArgs;
361/// #
362/// /// 1. Defines the `simple_udwf()` user-defined window function.
363/// ///
364/// /// 2. Defines the expression API:
365/// /// ```
366/// /// pub fn simple() -> datafusion_expr::Expr {
367/// /// simple_udwf().call(vec![])
368/// /// }
369/// /// ```
370/// define_udwf_and_expr!(
371/// SimpleUDWF,
372/// simple,
373/// "a simple user-defined window function"
374/// );
375/// #
376/// # assert_eq!(simple_udwf().name(), "simple_user_defined_window_function");
377/// #
378/// # #[derive(Debug)]
379/// # struct SimpleUDWF {
380/// # signature: Signature,
381/// # }
382/// #
383/// # impl Default for SimpleUDWF {
384/// # fn default() -> Self {
385/// # Self {
386/// # signature: Signature::any(0, Volatility::Immutable),
387/// # }
388/// # }
389/// # }
390/// #
391/// # impl WindowUDFImpl for SimpleUDWF {
392/// # fn as_any(&self) -> &dyn Any {
393/// # self
394/// # }
395/// # fn name(&self) -> &str {
396/// # "simple_user_defined_window_function"
397/// # }
398/// # fn signature(&self) -> &Signature {
399/// # &self.signature
400/// # }
401/// # fn partition_evaluator(
402/// # &self,
403/// # partition_evaluator_args: PartitionEvaluatorArgs,
404/// # ) -> datafusion_common::Result<Box<dyn PartitionEvaluator>> {
405/// # unimplemented!()
406/// # }
407/// # fn field(&self, field_args: WindowUDFFieldArgs) -> datafusion_common::Result<Field> {
408/// # Ok(Field::new(field_args.name(), DataType::Int64, false))
409/// # }
410/// # }
411/// #
412/// ```
413///
414/// 2. Uses a custom constructor for UDWF.
415///
416/// ```
417/// # use std::any::Any;
418/// # use datafusion_common::arrow::datatypes::{DataType, Field};
419/// # use datafusion_expr::{PartitionEvaluator, Signature, Volatility, WindowUDFImpl};
420/// # use datafusion_functions_window::{create_udwf_expr, define_udwf_and_expr, get_or_init_udwf};
421/// # use datafusion_functions_window_common::field::WindowUDFFieldArgs;
422/// # use datafusion_functions_window_common::partition::PartitionEvaluatorArgs;
423/// #
424/// /// 1. Defines the `row_number_udwf()` user-defined window function.
425/// ///
426/// /// 2. Defines the expression API:
427/// /// ```
428/// /// pub fn row_number() -> datafusion_expr::Expr {
429/// /// row_number_udwf().call(vec![])
430/// /// }
431/// /// ```
432/// define_udwf_and_expr!(
433/// RowNumber,
434/// row_number,
435/// "Returns a unique row number for each row in window partition beginning at 1.",
436/// RowNumber::new // <-- custom constructor
437/// );
438/// #
439/// # assert_eq!(
440/// # row_number().name_for_alias().unwrap(),
441/// # "row_number() ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING"
442/// # );
443/// #
444/// # #[derive(Debug)]
445/// # struct RowNumber {
446/// # signature: Signature,
447/// # }
448/// # impl RowNumber {
449/// # fn new() -> Self {
450/// # Self {
451/// # signature: Signature::any(0, Volatility::Immutable),
452/// # }
453/// # }
454/// # }
455/// # impl WindowUDFImpl for RowNumber {
456/// # fn as_any(&self) -> &dyn Any {
457/// # self
458/// # }
459/// # fn name(&self) -> &str {
460/// # "row_number"
461/// # }
462/// # fn signature(&self) -> &Signature {
463/// # &self.signature
464/// # }
465/// # fn partition_evaluator(
466/// # &self,
467/// # _partition_evaluator_args: PartitionEvaluatorArgs,
468/// # ) -> datafusion_common::Result<Box<dyn PartitionEvaluator>> {
469/// # unimplemented!()
470/// # }
471/// # fn field(&self, field_args: WindowUDFFieldArgs) -> datafusion_common::Result<Field> {
472/// # Ok(Field::new(field_args.name(), DataType::UInt64, false))
473/// # }
474/// # }
475/// ```
476///
477/// ## Expression API With Multiple Parameters
478/// 3. Uses default constructor for UDWF
479///
480/// ```
481/// # use std::any::Any;
482/// #
483/// # use datafusion_expr::{
484/// # PartitionEvaluator, Signature, TypeSignature, Volatility, WindowUDFImpl,
485/// # };
486/// #
487/// # use datafusion_functions_window::{create_udwf_expr, define_udwf_and_expr, get_or_init_udwf};
488/// # use datafusion_functions_window_common::field::WindowUDFFieldArgs;
489/// #
490/// # use datafusion_common::arrow::datatypes::Field;
491/// # use datafusion_common::ScalarValue;
492/// # use datafusion_expr::{col, lit};
493/// # use datafusion_functions_window_common::partition::PartitionEvaluatorArgs;
494/// #
495/// /// 1. Defines the `lead_udwf()` user-defined window function.
496/// ///
497/// /// 2. Defines the expression API:
498/// /// ```
499/// /// pub fn lead(
500/// /// expr: datafusion_expr::Expr,
501/// /// offset: datafusion_expr::Expr,
502/// /// default: datafusion_expr::Expr,
503/// /// ) -> datafusion_expr::Expr {
504/// /// lead_udwf().call(vec![expr, offset, default])
505/// /// }
506/// /// ```
507/// define_udwf_and_expr!(
508/// Lead,
509/// lead,
510/// [expr, offset, default], // <- 3 parameters
511/// "user-defined window function"
512/// );
513/// #
514/// # assert_eq!(
515/// # lead(col("a"), lit(1i64), lit(ScalarValue::Null))
516/// # .name_for_alias()
517/// # .unwrap(),
518/// # "lead(a,Int64(1),NULL) ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING"
519/// # );
520/// #
521/// # #[derive(Debug)]
522/// # struct Lead {
523/// # signature: Signature,
524/// # }
525/// #
526/// # impl Default for Lead {
527/// # fn default() -> Self {
528/// # Self {
529/// # signature: Signature::one_of(
530/// # vec![
531/// # TypeSignature::Any(1),
532/// # TypeSignature::Any(2),
533/// # TypeSignature::Any(3),
534/// # ],
535/// # Volatility::Immutable,
536/// # ),
537/// # }
538/// # }
539/// # }
540/// #
541/// # impl WindowUDFImpl for Lead {
542/// # fn as_any(&self) -> &dyn Any {
543/// # self
544/// # }
545/// # fn name(&self) -> &str {
546/// # "lead"
547/// # }
548/// # fn signature(&self) -> &Signature {
549/// # &self.signature
550/// # }
551/// # fn partition_evaluator(
552/// # &self,
553/// # _partition_evaluator_args: PartitionEvaluatorArgs,
554/// # ) -> datafusion_common::Result<Box<dyn PartitionEvaluator>> {
555/// # unimplemented!()
556/// # }
557/// # fn field(&self, field_args: WindowUDFFieldArgs) -> datafusion_common::Result<Field> {
558/// # Ok(Field::new(
559/// # field_args.name(),
560/// # field_args.get_input_type(0).unwrap(),
561/// # false,
562/// # ))
563/// # }
564/// # }
565/// ```
566/// 4. Uses custom constructor for UDWF
567///
568/// ```
569/// # use std::any::Any;
570/// #
571/// # use datafusion_expr::{
572/// # PartitionEvaluator, Signature, TypeSignature, Volatility, WindowUDFImpl,
573/// # };
574/// #
575/// # use datafusion_functions_window::{create_udwf_expr, define_udwf_and_expr, get_or_init_udwf};
576/// # use datafusion_functions_window_common::field::WindowUDFFieldArgs;
577/// #
578/// # use datafusion_common::arrow::datatypes::Field;
579/// # use datafusion_common::ScalarValue;
580/// # use datafusion_expr::{col, lit};
581/// # use datafusion_functions_window_common::partition::PartitionEvaluatorArgs;
582/// #
583/// /// 1. Defines the `lead_udwf()` user-defined window function.
584/// ///
585/// /// 2. Defines the expression API:
586/// /// ```
587/// /// pub fn lead(
588/// /// expr: datafusion_expr::Expr,
589/// /// offset: datafusion_expr::Expr,
590/// /// default: datafusion_expr::Expr,
591/// /// ) -> datafusion_expr::Expr {
592/// /// lead_udwf().call(vec![expr, offset, default])
593/// /// }
594/// /// ```
595/// define_udwf_and_expr!(
596/// Lead,
597/// lead,
598/// [expr, offset, default], // <- 3 parameters
599/// "user-defined window function",
600/// Lead::new // <- Custom constructor
601/// );
602/// #
603/// # assert_eq!(
604/// # lead(col("a"), lit(1i64), lit(ScalarValue::Null))
605/// # .name_for_alias()
606/// # .unwrap(),
607/// # "lead(a,Int64(1),NULL) ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING"
608/// # );
609/// #
610/// # #[derive(Debug)]
611/// # struct Lead {
612/// # signature: Signature,
613/// # }
614/// #
615/// # impl Lead {
616/// # fn new() -> Self {
617/// # Self {
618/// # signature: Signature::one_of(
619/// # vec![
620/// # TypeSignature::Any(1),
621/// # TypeSignature::Any(2),
622/// # TypeSignature::Any(3),
623/// # ],
624/// # Volatility::Immutable,
625/// # ),
626/// # }
627/// # }
628/// # }
629/// #
630/// # impl WindowUDFImpl for Lead {
631/// # fn as_any(&self) -> &dyn Any {
632/// # self
633/// # }
634/// # fn name(&self) -> &str {
635/// # "lead"
636/// # }
637/// # fn signature(&self) -> &Signature {
638/// # &self.signature
639/// # }
640/// # fn partition_evaluator(
641/// # &self,
642/// # _partition_evaluator_args: PartitionEvaluatorArgs,
643/// # ) -> datafusion_common::Result<Box<dyn PartitionEvaluator>> {
644/// # unimplemented!()
645/// # }
646/// # fn field(&self, field_args: WindowUDFFieldArgs) -> datafusion_common::Result<Field> {
647/// # Ok(Field::new(
648/// # field_args.name(),
649/// # field_args.get_input_type(0).unwrap(),
650/// # false,
651/// # ))
652/// # }
653/// # }
654/// ```
655#[macro_export]
656macro_rules! define_udwf_and_expr {
657 // Defines UDWF with default constructor
658 // Defines expression API with zero parameters
659 ($UDWF:ident, $OUT_FN_NAME:ident, $DOC:expr) => {
660 get_or_init_udwf!($UDWF, $OUT_FN_NAME, $DOC);
661 create_udwf_expr!($UDWF, $OUT_FN_NAME, $DOC);
662 };
663
664 // Defines UDWF by passing a custom constructor
665 // Defines expression API with zero parameters
666 ($UDWF:ident, $OUT_FN_NAME:ident, $DOC:expr, $CTOR:path) => {
667 get_or_init_udwf!($UDWF, $OUT_FN_NAME, $DOC, $CTOR);
668 create_udwf_expr!($UDWF, $OUT_FN_NAME, $DOC);
669 };
670
671 // Defines UDWF with default constructor
672 // Defines expression API with multiple parameters
673 ($UDWF:ident, $OUT_FN_NAME:ident, [$($PARAM:ident),+], $DOC:expr) => {
674 get_or_init_udwf!($UDWF, $OUT_FN_NAME, $DOC);
675 create_udwf_expr!($UDWF, $OUT_FN_NAME, [$($PARAM),+], $DOC);
676 };
677
678 // Defines UDWF by passing a custom constructor
679 // Defines expression API with multiple parameters
680 ($UDWF:ident, $OUT_FN_NAME:ident, [$($PARAM:ident),+], $DOC:expr, $CTOR:path) => {
681 get_or_init_udwf!($UDWF, $OUT_FN_NAME, $DOC, $CTOR);
682 create_udwf_expr!($UDWF, $OUT_FN_NAME, [$($PARAM),+], $DOC);
683 };
684}