Skip to content

Commit 6761ecd

Browse files
authored
Make config API more ergonomic (#535)
By implementing `AsRef<str>` on config enums and making them clonable. After some consideration, I decided not to pass config enums as references (and breaking the API in a minor way) because they are small unit variants, which many libraries choose to pass by value. Fixes #442
2 parents 9cebfbf + 0f28e5f commit 6761ecd

File tree

1 file changed

+18
-16
lines changed

1 file changed

+18
-16
lines changed

crates/duckdb/src/config.rs

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ use super::{ffi, Result};
22
use crate::error::Error;
33
use std::{default::Default, ffi::CString, os::raw::c_char, ptr};
44

5-
use strum::{Display, EnumString};
5+
use strum::{AsRefStr, Display, EnumString};
66

77
/// duckdb access mode, default is Automatic
8-
#[derive(Debug, Eq, PartialEq, EnumString, Display)]
8+
#[derive(Debug, Eq, PartialEq, Clone, EnumString, Display, AsRefStr)]
99
pub enum AccessMode {
1010
/// Access mode of the database AUTOMATIC
1111
#[strum(to_string = "AUTOMATIC")]
@@ -19,7 +19,7 @@ pub enum AccessMode {
1919
}
2020

2121
/// duckdb default order, default is Asc
22-
#[derive(Debug, Eq, PartialEq, EnumString, Display)]
22+
#[derive(Debug, Eq, PartialEq, Clone, EnumString, Display, AsRefStr)]
2323
pub enum DefaultOrder {
2424
/// The order type, ASC
2525
#[strum(to_string = "ASC")]
@@ -30,7 +30,7 @@ pub enum DefaultOrder {
3030
}
3131

3232
/// duckdb default null order, default is nulls first
33-
#[derive(Debug, Eq, PartialEq, EnumString, Display)]
33+
#[derive(Debug, Eq, PartialEq, Clone, EnumString, Display, AsRefStr)]
3434
pub enum DefaultNullOrder {
3535
/// Null ordering, NullsFirst
3636
#[strum(to_string = "NULLS_FIRST")]
@@ -54,14 +54,15 @@ impl Config {
5454

5555
/// enable autoload extensions
5656
pub fn enable_autoload_extension(mut self, enabled: bool) -> Result<Self> {
57-
self.set("autoinstall_known_extensions", &(enabled as i32).to_string())?;
58-
self.set("autoload_known_extensions", &(enabled as i32).to_string())?;
57+
let value = (enabled as u8).to_string();
58+
self.set("autoinstall_known_extensions", &value)?;
59+
self.set("autoload_known_extensions", &value)?;
5960
Ok(self)
6061
}
6162

6263
/// Access mode of the database ([AUTOMATIC], READ_ONLY or READ_WRITE)
6364
pub fn access_mode(mut self, mode: AccessMode) -> Result<Self> {
64-
self.set("access_mode", &mode.to_string())?;
65+
self.set("access_mode", mode)?;
6566
Ok(self)
6667
}
6768

@@ -73,25 +74,25 @@ impl Config {
7374

7475
/// The order type used when none is specified ([ASC] or DESC)
7576
pub fn default_order(mut self, order: DefaultOrder) -> Result<Self> {
76-
self.set("default_order", &order.to_string())?;
77+
self.set("default_order", order)?;
7778
Ok(self)
7879
}
7980

8081
/// Null ordering used when none is specified ([NULLS_FIRST] or NULLS_LAST)
8182
pub fn default_null_order(mut self, null_order: DefaultNullOrder) -> Result<Self> {
82-
self.set("default_null_order", &null_order.to_string())?;
83+
self.set("default_null_order", null_order)?;
8384
Ok(self)
8485
}
8586

8687
/// Allow the database to access external state (through e.g. COPY TO/FROM, CSV readers, pandas replacement scans, etc)
8788
pub fn enable_external_access(mut self, enabled: bool) -> Result<Self> {
88-
self.set("enable_external_access", &enabled.to_string())?;
89+
self.set("enable_external_access", enabled.to_string())?;
8990
Ok(self)
9091
}
9192

9293
/// Whether or not object cache is used to cache e.g. Parquet metadata
9394
pub fn enable_object_cache(mut self, enabled: bool) -> Result<Self> {
94-
self.set("enable_object_cache", &enabled.to_string())?;
95+
self.set("enable_object_cache", enabled.to_string())?;
9596
Ok(self)
9697
}
9798

@@ -109,18 +110,19 @@ impl Config {
109110

110111
/// The number of total threads used by the system
111112
pub fn threads(mut self, thread_num: i64) -> Result<Self> {
112-
self.set("threads", &thread_num.to_string())?;
113+
self.set("threads", thread_num.to_string())?;
113114
Ok(self)
114115
}
115116

116-
/// Add any setting to the config. DuckDB will return an error if the setting is unknown or
117-
/// otherwise invalid.
117+
/// Add any setting to the config. DuckDB will return an error if the setting is unknown or otherwise invalid.
118118
pub fn with(mut self, key: impl AsRef<str>, value: impl AsRef<str>) -> Result<Self> {
119-
self.set(key.as_ref(), value.as_ref())?;
119+
self.set(key, value)?;
120120
Ok(self)
121121
}
122122

123-
fn set(&mut self, key: &str, value: &str) -> Result<()> {
123+
fn set(&mut self, key: impl AsRef<str>, value: impl AsRef<str>) -> Result<()> {
124+
let key = key.as_ref();
125+
let value = value.as_ref();
124126
if self.config.is_none() {
125127
let mut config: ffi::duckdb_config = ptr::null_mut();
126128
let state = unsafe { ffi::duckdb_create_config(&mut config) };

0 commit comments

Comments
 (0)