This is an automated email from the ASF dual-hosted git repository.

mneumann pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git


The following commit(s) were added to refs/heads/main by this push:
     new 78433a7927 fix: document and fix macro hygiene for `config_field!` 
(#16473)
78433a7927 is described below

commit 78433a7927b531996057ad2a9224d115b637cd6f
Author: Marco Neumann <ma...@crepererum.net>
AuthorDate: Mon Jun 23 12:36:27 2025 +0200

    fix: document and fix macro hygiene for `config_field!` (#16473)
---
 datafusion/common/src/config.rs            | 41 +++++++++++++++++++++++++-----
 datafusion/core/tests/macro_hygiene/mod.rs | 37 +++++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 6 deletions(-)

diff --git a/datafusion/common/src/config.rs b/datafusion/common/src/config.rs
index f16e30969b..ac3f908e37 100644
--- a/datafusion/common/src/config.rs
+++ b/datafusion/common/src/config.rs
@@ -1248,7 +1248,10 @@ impl<F: ConfigField + Default> ConfigField for Option<F> 
{
     }
 }
 
-fn default_transform<T>(input: &str) -> Result<T>
+/// Default transformation to parse a [`ConfigField`] for a string.
+///
+/// This uses [`FromStr`] to parse the data.
+pub fn default_config_transform<T>(input: &str) -> Result<T>
 where
     T: FromStr,
     <T as FromStr>::Err: Sync + Send + Error + 'static,
@@ -1265,19 +1268,45 @@ where
     })
 }
 
+/// Macro that generates [`ConfigField`] for a given type.
+///
+/// # Usage
+/// This always requires [`Display`] to be implemented for the given type.
+///
+/// There are two ways to invoke this macro. The first one uses
+/// [`default_config_transform`]/[`FromStr`] to parse the data:
+///
+/// ```ignore
+/// config_field(MyType);
+/// ```
+///
+/// Note that the parsing error MUST implement [`std::error::Error`]!
+///
+/// Or you can specify how you want to parse an [`str`] into the type:
+///
+/// ```ignore
+/// fn parse_it(s: &str) -> Result<MyType> {
+///     ...
+/// }
+///
+/// config_field(
+///     MyType,
+///     value => parse_it(value)
+/// );
+/// ```
 #[macro_export]
 macro_rules! config_field {
     ($t:ty) => {
-        config_field!($t, value => default_transform(value)?);
+        config_field!($t, value => 
$crate::config::default_config_transform(value)?);
     };
 
     ($t:ty, $arg:ident => $transform:expr) => {
-        impl ConfigField for $t {
-            fn visit<V: Visit>(&self, v: &mut V, key: &str, description: 
&'static str) {
+        impl $crate::config::ConfigField for $t {
+            fn visit<V: $crate::config::Visit>(&self, v: &mut V, key: &str, 
description: &'static str) {
                 v.some(key, self, description)
             }
 
-            fn set(&mut self, _: &str, $arg: &str) -> Result<()> {
+            fn set(&mut self, _: &str, $arg: &str) -> 
$crate::error::Result<()> {
                 *self = $transform;
                 Ok(())
             }
@@ -1286,7 +1315,7 @@ macro_rules! config_field {
 }
 
 config_field!(String);
-config_field!(bool, value => 
default_transform(value.to_lowercase().as_str())?);
+config_field!(bool, value => 
default_config_transform(value.to_lowercase().as_str())?);
 config_field!(usize);
 config_field!(f64);
 config_field!(u64);
diff --git a/datafusion/core/tests/macro_hygiene/mod.rs 
b/datafusion/core/tests/macro_hygiene/mod.rs
index 9196efec97..e5396ce219 100644
--- a/datafusion/core/tests/macro_hygiene/mod.rs
+++ b/datafusion/core/tests/macro_hygiene/mod.rs
@@ -65,3 +65,40 @@ mod config_namespace {
         }
     }
 }
+
+mod config_field {
+    // NO other imports!
+    use datafusion_common::config_field;
+
+    #[test]
+    fn test_macro() {
+        #[derive(Debug)]
+        struct E;
+
+        impl std::fmt::Display for E {
+            fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> 
std::fmt::Result {
+                unimplemented!()
+            }
+        }
+
+        impl std::error::Error for E {}
+
+        struct S;
+
+        impl std::str::FromStr for S {
+            type Err = E;
+
+            fn from_str(_s: &str) -> Result<Self, Self::Err> {
+                unimplemented!()
+            }
+        }
+
+        impl std::fmt::Display for S {
+            fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> 
std::fmt::Result {
+                unimplemented!()
+            }
+        }
+
+        config_field!(S);
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@datafusion.apache.org
For additional commands, e-mail: commits-h...@datafusion.apache.org

Reply via email to