Skip to content

Commit

Permalink
refactor(service/libsql): Add LibsqlConfig to implement ConfigDeseria…
Browse files Browse the repository at this point in the history
…lizer (#3501)

* aa

* aa

* add missing /// libsqlservices docstring
  • Loading branch information
sd44 authored Nov 7, 2023
1 parent 87a7ac1 commit 3e2114d
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 28 deletions.
71 changes: 43 additions & 28 deletions core/src/services/libsql/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,19 @@ use hrana_client_proto::pipeline::{
use hrana_client_proto::Error as PipelineError;
use hrana_client_proto::{Stmt, StmtResult, Value};
use http::{Request, Uri};
use serde::Deserialize;

use crate::raw::adapters::kv;
use crate::raw::*;
use crate::*;

use super::error::parse_error;

#[doc = include_str!("docs.md")]
#[derive(Default)]
pub struct LibsqlBuilder {
/// Config for Libsqlservices support.
#[derive(Default, Deserialize)]
#[serde(default)]
#[non_exhaustive]
pub struct LibsqlConfig {
connection_string: Option<String>,
auth_token: Option<String>,

Expand All @@ -47,7 +50,7 @@ pub struct LibsqlBuilder {
root: Option<String>,
}

impl Debug for LibsqlBuilder {
impl Debug for LibsqlConfig {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut ds = f.debug_struct("LibsqlBuilder");
ds.field("connection_string", &self.connection_string)
Expand All @@ -59,10 +62,26 @@ impl Debug for LibsqlBuilder {
if self.auth_token.is_some() {
ds.field("auth_token", &"<redacted>");
}

ds.finish()
}
}

#[doc = include_str!("docs.md")]
#[derive(Default)]
pub struct LibsqlBuilder {
config: LibsqlConfig,
}

impl Debug for LibsqlBuilder {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut d = f.debug_struct("LibsqlBuilder");

d.field("config", &self.config);
d.finish()
}
}

impl LibsqlBuilder {
/// Set the connection_string of the libsql service.
///
Expand All @@ -79,7 +98,7 @@ impl LibsqlBuilder {
/// - `libsql://example.com/db`
pub fn connection_string(&mut self, v: &str) -> &mut Self {
if !v.is_empty() {
self.connection_string = Some(v.to_string());
self.config.connection_string = Some(v.to_string());
}
self
}
Expand All @@ -89,7 +108,7 @@ impl LibsqlBuilder {
/// default: no authentication token
pub fn auth_token(&mut self, auth_token: &str) -> &mut Self {
if !auth_token.is_empty() {
self.auth_token = Some(auth_token.to_owned());
self.config.auth_token = Some(auth_token.to_owned());
}
self
}
Expand All @@ -99,15 +118,15 @@ impl LibsqlBuilder {
/// default: "/"
pub fn root(&mut self, root: &str) -> &mut Self {
if !root.is_empty() {
self.root = Some(root.to_string());
self.config.root = Some(root.to_string());
}
self
}

/// Set the table name of the libsql service to read/write.
pub fn table(&mut self, table: &str) -> &mut Self {
if !table.is_empty() {
self.table = Some(table.to_string());
self.config.table = Some(table.to_string());
}
self
}
Expand All @@ -117,7 +136,7 @@ impl LibsqlBuilder {
/// 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
}
Expand All @@ -127,7 +146,7 @@ impl LibsqlBuilder {
/// 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
}
Expand All @@ -138,37 +157,33 @@ impl Builder for LibsqlBuilder {
type Accessor = LibsqlBackend;

fn from_map(map: HashMap<String, String>) -> Self {
let mut builder = LibsqlBuilder::default();
map.get("connection_string")
.map(|v| builder.connection_string(v));
map.get("auth_token").map(|v| builder.auth_token(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));
map.get("root").map(|v| builder.root(v));
builder
let config = LibsqlConfig::deserialize(ConfigDeserializer::new(map))
.expect("config deserialize must succeed");

LibsqlBuilder { config }
}

fn build(&mut self) -> Result<Self::Accessor> {
let conn = self.get_connection_string()?;

let table = match self.table.clone() {
let table = match self.config.table.clone() {
Some(v) => v,
None => {
return Err(Error::new(ErrorKind::ConfigInvalid, "table is empty")
.with_context("service", Scheme::Libsql))
}
};
let key_field = match self.key_field.clone() {
let key_field = match self.config.key_field.clone() {
Some(v) => v,
None => "key".to_string(),
};
let value_field = match self.value_field.clone() {
let value_field = match self.config.value_field.clone() {
Some(v) => v,
None => "value".to_string(),
};
let root = normalize_root(
self.root
self.config
.root
.clone()
.unwrap_or_else(|| "/".to_string())
.as_str(),
Expand All @@ -182,7 +197,7 @@ impl Builder for LibsqlBuilder {
Ok(LibsqlBackend::new(Adapter {
client,
connection_string: conn,
auth_token: self.auth_token.clone(),
auth_token: self.config.auth_token.clone(),
table,
key_field,
value_field,
Expand All @@ -193,10 +208,10 @@ impl Builder for LibsqlBuilder {

impl LibsqlBuilder {
fn get_connection_string(&self) -> Result<String> {
let connection_string = self
.connection_string
.clone()
.ok_or_else(|| Error::new(ErrorKind::ConfigInvalid, "connection_string is empty"))?;
let connection_string =
self.config.connection_string.clone().ok_or_else(|| {
Error::new(ErrorKind::ConfigInvalid, "connection_string is empty")
})?;

let ep_url = connection_string
.replace("libsql://", "https://")
Expand Down
1 change: 1 addition & 0 deletions core/src/services/libsql/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@

mod backend;
pub use backend::LibsqlBuilder as Libsql;
pub use backend::LibsqlConfig;

mod error;
2 changes: 2 additions & 0 deletions core/src/services/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ pub use ipmfs::Ipmfs;
mod libsql;
#[cfg(feature = "services-libsql")]
pub use libsql::Libsql;
#[cfg(feature = "services-libsql")]
pub use libsql::LibsqlConfig;

#[cfg(feature = "services-memcached")]
mod memcached;
Expand Down

0 comments on commit 3e2114d

Please sign in to comment.