From 96584ca654e2b842234b2ff466b7e1ae82329436 Mon Sep 17 00:00:00 2001 From: jihuayu Date: Fri, 2 Feb 2024 10:27:47 +0800 Subject: [PATCH 1/5] Add D1Config #3240 --- core/src/services/d1/backend.rs | 89 ++++++++++++++++++++------------- core/src/services/d1/mod.rs | 2 + core/src/services/mod.rs | 2 + 3 files changed, 57 insertions(+), 36 deletions(-) diff --git a/core/src/services/d1/backend.rs b/core/src/services/d1/backend.rs index 5555c6bd57e..9eaa229fd0b 100644 --- a/core/src/services/d1/backend.rs +++ b/core/src/services/d1/backend.rs @@ -23,6 +23,7 @@ use async_trait::async_trait; use http::header; use http::Request; use http::StatusCode; +use serde::Deserialize; use serde_json::Value; use super::error::parse_error; @@ -32,29 +33,51 @@ use crate::raw::*; use crate::ErrorKind; use crate::*; +#[derive(Default, Deserialize)] +#[serde(default)] +#[non_exhaustive] +pub struct D1Config { + /// Set the token of cloudflare api. + pub token: Option, + /// Set the account id of cloudflare api. + pub account_id: Option, + /// Set the database id of cloudflare api. + pub database_id: Option, + + /// Set the working directory of OpenDAL. + pub root: Option, + /// Set the table of D1 Database. + pub table: Option, + /// Set the key field of D1 Database. + pub key_field: Option, + /// Set the value field of D1 Database. + pub value_field: Option, +} + #[doc = include_str!("docs.md")] #[derive(Default)] pub struct D1Builder { - token: Option, - account_id: Option, - database_id: Option, + config: D1Config, http_client: Option, - root: Option, - - table: Option, - key_field: Option, - value_field: Option, } -impl Debug for D1Builder { +impl Debug for D1Config { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let mut ds = f.debug_struct("D1Builder"); + let mut ds = f.debug_struct("D1Config"); ds.field("root", &self.root); ds.field("table", &self.table); ds.field("key_field", &self.key_field); ds.field("value_field", &self.value_field); - ds.finish() + ds.finish_non_exhaustive() + } +} + +impl Debug for D1Builder { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("D1Builder") + .field("config", &self.config) + .finish() } } @@ -64,7 +87,7 @@ impl D1Builder { /// create a api token from [here](https://dash.cloudflare.com/profile/api-tokens) pub fn token(&mut self, token: &str) -> &mut Self { if !token.is_empty() { - self.token = Some(token.to_string()); + self.config.token = Some(token.to_string()); } self } @@ -75,7 +98,7 @@ impl D1Builder { /// If not specified, it will return an error when building. pub fn account_id(&mut self, account_id: &str) -> &mut Self { if !account_id.is_empty() { - self.account_id = Some(account_id.to_string()); + self.config.account_id = Some(account_id.to_string()); } self } @@ -86,7 +109,7 @@ impl D1Builder { /// If not specified, it will return an error when building. pub fn database_id(&mut self, database_id: &str) -> &mut Self { if !database_id.is_empty() { - self.database_id = Some(database_id.to_string()); + self.config.database_id = Some(database_id.to_string()); } self } @@ -96,7 +119,7 @@ impl D1Builder { /// default: "/" pub fn root(&mut self, root: &str) -> &mut Self { if !root.is_empty() { - self.root = Some(root.to_owned()); + self.config.root = Some(root.to_owned()); } self } @@ -106,7 +129,7 @@ impl D1Builder { /// If not specified, it will return an error when building. pub fn table(&mut self, table: &str) -> &mut Self { if !table.is_empty() { - self.table = Some(table.to_owned()); + self.config.table = Some(table.to_owned()); } self } @@ -116,7 +139,7 @@ impl D1Builder { /// Default to `key` if not specified. pub fn key_field(&mut self, key_field: &str) -> &mut Self { if !key_field.is_empty() { - self.key_field = Some(key_field.to_string()); + self.config.key_field = Some(key_field.to_string()); } self } @@ -126,7 +149,7 @@ impl D1Builder { /// Default to `value` if not specified. pub fn value_field(&mut self, value_field: &str) -> &mut Self { if !value_field.is_empty() { - self.value_field = Some(value_field.to_string()); + self.config.value_field = Some(value_field.to_string()); } self } @@ -137,32 +160,26 @@ impl Builder for D1Builder { type Accessor = D1Backend; fn from_map(map: HashMap) -> Self { - let mut builder = D1Builder::default(); - map.get("token").map(|v| builder.token(v)); - map.get("account_id").map(|v| builder.account_id(v)); - map.get("database_id").map(|v| builder.database_id(v)); - - map.get("root").map(|v| builder.root(v)); - map.get("table").map(|v| builder.table(v)); - map.get("key_field").map(|v| builder.key_field(v)); - map.get("value_field").map(|v| builder.value_field(v)); - builder + let config = D1Config::deserialize(ConfigDeserializer::new(map)) + .expect("config deserialize must succeed"); + Builder { config } } fn build(&mut self) -> Result { let mut authorization = None; - if let Some(token) = &self.token { + let config = &self.config; + if let Some(token) = &config.token { authorization = Some(format_authorization_by_bearer(token)?) } - let Some(account_id) = self.account_id.clone() else { + let Some(account_id) = config.account_id.clone() else { return Err(Error::new( ErrorKind::ConfigInvalid, "account_id is required", )); }; - let Some(database_id) = self.database_id.clone() else { + let Some(database_id) = config.database_id.clone() else { return Err(Error::new( ErrorKind::ConfigInvalid, "database_id is required", @@ -178,19 +195,19 @@ impl Builder for D1Builder { })? }; - let Some(table) = self.table.clone() else { + let Some(table) = config.table.clone() else { return Err(Error::new(ErrorKind::ConfigInvalid, "table is required")); }; - let key_field = self.key_field.clone().unwrap_or_else(|| "key".to_string()); + let key_field = config.key_field.clone().unwrap_or_else(|| "key".to_string()); - let value_field = self + let value_field = config .value_field .clone() .unwrap_or_else(|| "value".to_string()); let root = normalize_root( - self.root + config.root .clone() .unwrap_or_else(|| "/".to_string()) .as_str(), @@ -204,7 +221,7 @@ impl Builder for D1Builder { key_field, value_field, }) - .with_root(&root)) + .with_root(&root)) } } diff --git a/core/src/services/d1/mod.rs b/core/src/services/d1/mod.rs index 9163a135c6c..1fe63408aff 100644 --- a/core/src/services/d1/mod.rs +++ b/core/src/services/d1/mod.rs @@ -18,4 +18,6 @@ mod backend; mod error; mod model; + pub use backend::D1Builder as D1; +pub use backend::D1Config; diff --git a/core/src/services/mod.rs b/core/src/services/mod.rs index 16f467329b6..1a2ceb26064 100644 --- a/core/src/services/mod.rs +++ b/core/src/services/mod.rs @@ -292,6 +292,8 @@ pub use sqlite::SqliteConfig; mod d1; #[cfg(feature = "services-d1")] pub use self::d1::D1; +#[cfg(feature = "services-d1")] +pub use self::d1::D1Config; #[cfg(feature = "services-azfile")] mod azfile; From aa90fb6ab98bf93320c75bfe806647506a04087e Mon Sep 17 00:00:00 2001 From: jihuayu Date: Fri, 2 Feb 2024 10:30:36 +0800 Subject: [PATCH 2/5] Add D1Config #3240 --- core/src/services/d1/backend.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/services/d1/backend.rs b/core/src/services/d1/backend.rs index 9eaa229fd0b..fcb4a55d88e 100644 --- a/core/src/services/d1/backend.rs +++ b/core/src/services/d1/backend.rs @@ -54,14 +54,6 @@ pub struct D1Config { pub value_field: Option, } -#[doc = include_str!("docs.md")] -#[derive(Default)] -pub struct D1Builder { - config: D1Config, - - http_client: Option, -} - impl Debug for D1Config { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { let mut ds = f.debug_struct("D1Config"); @@ -73,6 +65,14 @@ impl Debug for D1Config { } } +#[doc = include_str!("docs.md")] +#[derive(Default)] +pub struct D1Builder { + config: D1Config, + + http_client: Option, +} + impl Debug for D1Builder { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("D1Builder") From c8f279e414c78adc6a2816e3f47e924360c4c35d Mon Sep 17 00:00:00 2001 From: jihuayu Date: Fri, 2 Feb 2024 10:31:46 +0800 Subject: [PATCH 3/5] format code --- core/src/services/d1/backend.rs | 10 +++++++--- core/src/services/mod.rs | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/core/src/services/d1/backend.rs b/core/src/services/d1/backend.rs index fcb4a55d88e..749ae50e6aa 100644 --- a/core/src/services/d1/backend.rs +++ b/core/src/services/d1/backend.rs @@ -199,7 +199,10 @@ impl Builder for D1Builder { return Err(Error::new(ErrorKind::ConfigInvalid, "table is required")); }; - let key_field = config.key_field.clone().unwrap_or_else(|| "key".to_string()); + let key_field = config + .key_field + .clone() + .unwrap_or_else(|| "key".to_string()); let value_field = config .value_field @@ -207,7 +210,8 @@ impl Builder for D1Builder { .unwrap_or_else(|| "value".to_string()); let root = normalize_root( - config.root + config + .root .clone() .unwrap_or_else(|| "/".to_string()) .as_str(), @@ -221,7 +225,7 @@ impl Builder for D1Builder { key_field, value_field, }) - .with_root(&root)) + .with_root(&root)) } } diff --git a/core/src/services/mod.rs b/core/src/services/mod.rs index 1a2ceb26064..de5c0cef022 100644 --- a/core/src/services/mod.rs +++ b/core/src/services/mod.rs @@ -291,9 +291,9 @@ pub use sqlite::SqliteConfig; #[cfg(feature = "services-d1")] mod d1; #[cfg(feature = "services-d1")] -pub use self::d1::D1; -#[cfg(feature = "services-d1")] pub use self::d1::D1Config; +#[cfg(feature = "services-d1")] +pub use self::d1::D1; #[cfg(feature = "services-azfile")] mod azfile; From f40ac18ed95fbe562acd18c6c79c64cb088fec7d Mon Sep 17 00:00:00 2001 From: jihuayu Date: Fri, 2 Feb 2024 11:21:48 +0800 Subject: [PATCH 4/5] fix bug --- core/src/services/d1/backend.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/src/services/d1/backend.rs b/core/src/services/d1/backend.rs index 749ae50e6aa..ccae2388f1a 100644 --- a/core/src/services/d1/backend.rs +++ b/core/src/services/d1/backend.rs @@ -160,9 +160,11 @@ impl Builder for D1Builder { type Accessor = D1Backend; fn from_map(map: HashMap) -> Self { - let config = D1Config::deserialize(ConfigDeserializer::new(map)) - .expect("config deserialize must succeed"); - Builder { config } + Self { + config: D1Config::deserialize(ConfigDeserializer::new(map)) + .expect("config deserialize must succeed"), + ..Default::default() + } } fn build(&mut self) -> Result { From b9cac09c172ee049f08e1f2cec931c4af697d4e7 Mon Sep 17 00:00:00 2001 From: jihuayu Date: Fri, 2 Feb 2024 11:37:18 +0800 Subject: [PATCH 5/5] fix cargo clippy --- core/src/services/d1/backend.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/services/d1/backend.rs b/core/src/services/d1/backend.rs index ccae2388f1a..203ad4d2d93 100644 --- a/core/src/services/d1/backend.rs +++ b/core/src/services/d1/backend.rs @@ -33,6 +33,7 @@ use crate::raw::*; use crate::ErrorKind; use crate::*; +/// Config for [Cloudflare D1](https://developers.cloudflare.com/d1) backend support. #[derive(Default, Deserialize)] #[serde(default)] #[non_exhaustive]