feat(config): implement config builder pattern for ClientConfig

- introduce ConfigBuilder struct for constructing ClientConfig instances
- add methods to ConfigBuilder for setting various configuration parameters
- implement a build method to create the ClientConfig instance
- add a default implementation for ConfigBuilder
- enhance ClientConfig with persist_path for token persistence
- update ClientConfig::new_from_configuration to use config_root.full_path()
- add ClientConfig::persist_path() to report the full path to the file to persist tokens
This commit is contained in:
Jeremiah Russell
2025-10-16 15:29:11 +01:00
committed by Jeremiah Russell
parent a6d5186cd9
commit 368e78b1cc

View File

@@ -14,9 +14,15 @@ use config_root::ConfigRoot;
pub struct ClientConfig { pub struct ClientConfig {
secret: ApplicationSecret, secret: ApplicationSecret,
config_root: ConfigRoot, config_root: ConfigRoot,
persist_path: String,
} }
impl ClientConfig { impl ClientConfig {
/// Config Builder
pub fn builder() -> ConfigBuilder {
ConfigBuilder::default()
}
/// Create new configuration from configuration /// Create new configuration from configuration
pub fn new_from_configuration(configs: Config) -> Result<Self> { pub fn new_from_configuration(configs: Config) -> Result<Self> {
let root = configs.get_string("config_root")?; let root = configs.get_string("config_root")?;
@@ -41,7 +47,7 @@ impl ClientConfig {
} else { } else {
let credential_file = configs.get_string("credential_file")?; let credential_file = configs.get_string("credential_file")?;
log::info!("root: {config_root}"); log::info!("root: {config_root}");
let path = PathBuf::from(config_root.to_string()).join(credential_file); let path = config_root.full_path().join(credential_file);
log::info!("path: {}", path.display()); log::info!("path: {}", path.display());
let json_str = fs::read_to_string(path).expect("could not read path"); let json_str = fs::read_to_string(path).expect("could not read path");
@@ -51,9 +57,12 @@ impl ClientConfig {
console.installed.unwrap() console.installed.unwrap()
}; };
let persist_path = format!("{}/gmail1", config_root.full_path().display());
Ok(ClientConfig { Ok(ClientConfig {
config_root, config_root,
secret, secret,
persist_path,
}) })
} }
@@ -62,8 +71,120 @@ impl ClientConfig {
&self.secret &self.secret
} }
/// Report a reference to the full path to the file to persist tokens
pub fn persist_path(&self) -> &str {
&self.persist_path
}
/// Report a reference to the config root. /// Report a reference to the config root.
pub fn config_root(&self) -> &ConfigRoot { pub fn config_root(&self) -> &ConfigRoot {
&self.config_root &self.config_root
} }
/// Report a reference to the config root.
pub fn full_path(&self) -> String {
self.config_root.full_path().display().to_string()
}
}
#[derive(Debug)]
pub struct ConfigBuilder {
secret: ApplicationSecret,
config_root: ConfigRoot,
}
impl Default for ConfigBuilder {
fn default() -> Self {
let secret = ApplicationSecret {
auth_uri: "https;://accounts.google.com/o/oauth2/auth".to_string(),
token_uri: "https://oauth2.googleapis.com/token".to_string(),
..Default::default()
};
Self {
secret,
config_root: Default::default(),
}
}
}
impl ConfigBuilder {
pub fn with_config_base(&mut self, value: &config_root::RootBase) -> &mut Self {
self.config_root.set_root_base(value);
self
}
pub fn with_config_path(&mut self, value: &str) -> &mut Self {
self.config_root.set_path(value);
self
}
pub fn with_credential_file(&mut self, credential_file: &str) -> &mut Self {
let path = PathBuf::from(self.config_root.to_string()).join(credential_file);
log::info!("path: {}", path.display());
let json_str = fs::read_to_string(path).expect("could not read path");
let console: ConsoleApplicationSecret =
serde_json::from_str(&json_str).expect("could not convert to struct");
self.secret = console.installed.unwrap();
self
}
pub fn with_client_id(&mut self, value: &str) -> &mut Self {
self.secret.client_id = value.to_string();
self
}
pub fn with_client_secret(&mut self, value: &str) -> &mut Self {
self.secret.client_secret = value.to_string();
self
}
pub fn with_token_uri(&mut self, value: &str) -> &mut Self {
self.secret.token_uri = value.to_string();
self
}
pub fn with_auth_uri(&mut self, value: &str) -> &mut Self {
self.secret.auth_uri = value.to_string();
self
}
pub fn add_redirect_uri(&mut self, value: &str) -> &mut Self {
self.secret.redirect_uris.push(value.to_string());
self
}
pub fn with_project_id(&mut self, value: &str) -> &mut Self {
self.secret.project_id = Some(value.to_string());
self
}
pub fn with_client_email(&mut self, value: &str) -> &mut Self {
self.secret.client_email = Some(value.to_string());
self
}
pub fn with_auth_provider_x509_cert_url(&mut self, value: &str) -> &mut Self {
self.secret.auth_provider_x509_cert_url = Some(value.to_string());
self
}
pub fn with_client_x509_cert_url(&mut self, value: &str) -> &mut Self {
self.secret.client_x509_cert_url = Some(value.to_string());
self
}
fn full_path(&self) -> String {
self.config_root.full_path().display().to_string()
}
pub fn build(&self) -> ClientConfig {
let persist_path = format!("{}/gmail1", self.full_path());
ClientConfig {
secret: self.secret.clone(),
config_root: self.config_root.clone(),
persist_path,
}
}
} }