pub struct Config { /* private fields */ }Expand description
Configuration management for aster.
This module provides a flexible configuration system that supports:
- Dynamic configuration keys
- Multiple value types through serde deserialization
- Environment variable overrides
- YAML-based configuration file storage
- Hot reloading of configuration changes
- Secure secret storage in system keyring
Configuration values are loaded with the following precedence:
- Environment variables (exact key match)
- Configuration file (~/.config/aster/config.yaml by default)
Secrets are loaded with the following precedence:
- Environment variables (exact key match)
- System keyring (which can be disabled with ASTER_DISABLE_KEYRING)
- If the keyring is disabled, secrets are stored in a secrets file (~/.config/aster/secrets.yaml by default)
§Examples
use aster::config::Config;
use serde::Deserialize;
// Get a string value
let config = Config::global();
let api_key: String = config.get_param("OPENAI_API_KEY").unwrap();
// Get a complex type
#[derive(Deserialize)]
struct ServerConfig {
host: String,
port: u16,
}
let server_config: ServerConfig = config.get_param("server").unwrap();§Naming Convention
we recommend snake_case for keys, and will convert to UPPERCASE when checking for environment overrides. e.g. openai_api_key will check for an environment variable OPENAI_API_KEY
For aster-specific configuration, consider prefixing with “aster_” to avoid conflicts.
Implementations§
Source§impl Config
impl Config
Sourcepub fn global() -> &'static Config
pub fn global() -> &'static Config
Get the global configuration instance.
This will initialize the configuration with the default path (~/.config/aster/config.yaml) if it hasn’t been initialized yet.
Sourcepub fn new<P: AsRef<Path>>(
config_path: P,
service: &str,
) -> Result<Self, ConfigError>
pub fn new<P: AsRef<Path>>( config_path: P, service: &str, ) -> Result<Self, ConfigError>
Create a new configuration instance with custom paths
This is primarily useful for testing or for applications that need to manage multiple configuration files.
Sourcepub fn new_with_file_secrets<P1: AsRef<Path>, P2: AsRef<Path>>(
config_path: P1,
secrets_path: P2,
) -> Result<Self, ConfigError>
pub fn new_with_file_secrets<P1: AsRef<Path>, P2: AsRef<Path>>( config_path: P1, secrets_path: P2, ) -> Result<Self, ConfigError>
Create a new configuration instance with custom paths
This is primarily useful for testing or for applications that need to manage multiple configuration files.
pub fn exists(&self) -> bool
pub fn clear(&self) -> Result<(), ConfigError>
pub fn path(&self) -> String
pub fn all_values(&self) -> Result<HashMap<String, Value>, ConfigError>
pub fn initialize_if_empty(&self, values: Mapping) -> Result<(), ConfigError>
pub fn all_secrets(&self) -> Result<HashMap<String, Value>, ConfigError>
pub fn get(&self, key: &str, is_secret: bool) -> Result<Value, ConfigError>
pub fn set<V>(
&self,
key: &str,
value: &V,
is_secret: bool,
) -> Result<(), ConfigError>where
V: Serialize,
Sourcepub fn get_param<T: for<'de> Deserialize<'de>>(
&self,
key: &str,
) -> Result<T, ConfigError>
pub fn get_param<T: for<'de> Deserialize<'de>>( &self, key: &str, ) -> Result<T, ConfigError>
Get a configuration value (non-secret).
This will attempt to get the value from:
- Environment variable with the exact key name
- Configuration file
The value will be deserialized into the requested type. This works with both simple types (String, i32, etc.) and complex types that implement serde::Deserialize.
§Errors
Returns a ConfigError if:
- The key doesn’t exist in either environment or config file
- The value cannot be deserialized into the requested type
- There is an error reading the config file
Sourcepub fn set_param<V: Serialize>(
&self,
key: &str,
value: V,
) -> Result<(), ConfigError>
pub fn set_param<V: Serialize>( &self, key: &str, value: V, ) -> Result<(), ConfigError>
Set a configuration value in the config file (non-secret).
This will immediately write the value to the config file. The value can be any type that can be serialized to JSON/YAML.
Note that this does not affect environment variables - those can only be set through the system environment.
§Errors
Returns a ConfigError if:
- There is an error reading or writing the config file
- There is an error serializing the value
Sourcepub fn delete(&self, key: &str) -> Result<(), ConfigError>
pub fn delete(&self, key: &str) -> Result<(), ConfigError>
Delete a configuration value in the config file.
This will immediately write the value to the config file. The value can be any type that can be serialized to JSON/YAML.
Note that this does not affect environment variables - those can only be set through the system environment.
§Errors
Returns a ConfigError if:
- There is an error reading or writing the config file
- There is an error serializing the value
Sourcepub fn get_secret<T: for<'de> Deserialize<'de>>(
&self,
key: &str,
) -> Result<T, ConfigError>
pub fn get_secret<T: for<'de> Deserialize<'de>>( &self, key: &str, ) -> Result<T, ConfigError>
Get a secret value.
This will attempt to get the value from:
- Environment variable with the exact key name
- System keyring
The value will be deserialized into the requested type. This works with both simple types (String, i32, etc.) and complex types that implement serde::Deserialize.
§Errors
Returns a ConfigError if:
- The key doesn’t exist in either environment or keyring
- The value cannot be deserialized into the requested type
- There is an error accessing the keyring
Sourcepub fn get_secrets(
&self,
primary: &str,
maybe_secret: &[&str],
) -> Result<HashMap<String, String>, ConfigError>
pub fn get_secrets( &self, primary: &str, maybe_secret: &[&str], ) -> Result<HashMap<String, String>, ConfigError>
Get secrets. If primary is in env, use env for all keys. Otherwise use secret storage.
Sourcepub fn set_secret<V>(&self, key: &str, value: &V) -> Result<(), ConfigError>where
V: Serialize,
pub fn set_secret<V>(&self, key: &str, value: &V) -> Result<(), ConfigError>where
V: Serialize,
Set a secret value in the system keyring.
This will store the value in a single JSON object in the system keyring, alongside any other secrets. The value can be any type that can be serialized to JSON.
Note that this does not affect environment variables - those can only be set through the system environment.
§Errors
Returns a ConfigError if:
- There is an error accessing the keyring
- There is an error serializing the value
Sourcepub fn delete_secret(&self, key: &str) -> Result<(), ConfigError>
pub fn delete_secret(&self, key: &str) -> Result<(), ConfigError>
Delete a secret from the system keyring.
This will remove the specified key from the JSON object in the system keyring. Other secrets will remain unchanged.
§Errors
Returns a ConfigError if:
- There is an error accessing the keyring
- There is an error serializing the remaining values
Source§impl Config
impl Config
pub fn get_claude_code_command(&self) -> Result<ClaudeCodeCommand, ConfigError>
pub fn set_claude_code_command( &self, v: impl Into<ClaudeCodeCommand>, ) -> Result<(), ConfigError>
Source§impl Config
impl Config
pub fn get_gemini_cli_command(&self) -> Result<GeminiCliCommand, ConfigError>
pub fn set_gemini_cli_command( &self, v: impl Into<GeminiCliCommand>, ) -> Result<(), ConfigError>
Source§impl Config
impl Config
pub fn get_cursor_agent_command( &self, ) -> Result<CursorAgentCommand, ConfigError>
pub fn set_cursor_agent_command( &self, v: impl Into<CursorAgentCommand>, ) -> Result<(), ConfigError>
Source§impl Config
impl Config
pub fn get_codex_command(&self) -> Result<CodexCommand, ConfigError>
pub fn set_codex_command( &self, v: impl Into<CodexCommand>, ) -> Result<(), ConfigError>
Source§impl Config
impl Config
pub fn get_codex_reasoning_effort( &self, ) -> Result<CodexReasoningEffort, ConfigError>
pub fn set_codex_reasoning_effort( &self, v: impl Into<CodexReasoningEffort>, ) -> Result<(), ConfigError>
Source§impl Config
impl Config
pub fn get_codex_enable_skills(&self) -> Result<CodexEnableSkills, ConfigError>
pub fn set_codex_enable_skills( &self, v: impl Into<CodexEnableSkills>, ) -> Result<(), ConfigError>
Source§impl Config
impl Config
pub fn get_codex_skip_git_check(&self) -> Result<CodexSkipGitCheck, ConfigError>
pub fn set_codex_skip_git_check( &self, v: impl Into<CodexSkipGitCheck>, ) -> Result<(), ConfigError>
Source§impl Config
impl Config
pub fn get_codex_use_app_server(&self) -> Result<CodexUseAppServer, ConfigError>
pub fn set_codex_use_app_server( &self, v: impl Into<CodexUseAppServer>, ) -> Result<(), ConfigError>
Source§impl Config
impl Config
pub fn get_aster_search_paths(&self) -> Result<Vec<String>, ConfigError>
pub fn set_aster_search_paths( &self, v: impl Into<Vec<String>>, ) -> Result<(), ConfigError>
Source§impl Config
impl Config
pub fn get_aster_mode(&self) -> Result<AsterMode, ConfigError>
pub fn set_aster_mode(&self, v: impl Into<AsterMode>) -> Result<(), ConfigError>
Source§impl Config
impl Config
pub fn get_aster_provider(&self) -> Result<String, ConfigError>
pub fn set_aster_provider( &self, v: impl Into<String>, ) -> Result<(), ConfigError>
Source§impl Config
impl Config
pub fn get_aster_model(&self) -> Result<String, ConfigError>
pub fn set_aster_model(&self, v: impl Into<String>) -> Result<(), ConfigError>
Source§impl Config
impl Config
pub fn get_aster_max_active_agents(&self) -> Result<usize, ConfigError>
pub fn set_aster_max_active_agents( &self, v: impl Into<usize>, ) -> Result<(), ConfigError>
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for Config
impl RefUnwindSafe for Config
impl Send for Config
impl Sync for Config
impl Unpin for Config
impl UnsafeUnpin for Config
impl UnwindSafe for Config
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
Source§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::RequestSource§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.