pub struct Config {
pub workspace_path: String,
pub last_path: String,
pub theme_preference: String,
pub theme_mode: String,
pub fast: Provider,
pub standard: Provider,
pub thinking: Provider,
pub extract: Provider,
pub instruct: Provider,
pub coder: Provider,
}Expand description
Persistent configuration for the process.
Stored as TOML at a platform-specific location derived from AppName.
Fields§
§workspace_path: StringWorkspace root path.
last_path: StringLast opened path.
theme_preference: StringTheme
theme_mode: StringTheme Mode (light|dark|auto)
fast: ProviderProvider for fast inference tasks.
standard: ProviderProvider for standard inference tasks.
thinking: ProviderProvider for advanced reasoning tasks.
extract: ProviderProvider for extraction / large-context tasks.
instruct: ProviderProvider for instruction-following tasks.
coder: ProviderProvider for coding and AIM formula tasks.
Implementations§
Source§impl Config
impl Config
Sourcepub fn read_lock() -> Result<RwLockReadGuard<'static, Self>, Box<dyn Error>>
pub fn read_lock() -> Result<RwLockReadGuard<'static, Self>, Box<dyn Error>>
§Acquire a read guard for the global config.
§title: Read Lock
This function acquires a read lock on the global configuration singleton, providing thread-safe access to configuration data for reading operations.
§Returns
Returns a Result<RwLockReadGuard<'static, Config>> containing:
Ok(guard)- A read guard that provides immutable access to the configurationErr(error)- An error if the configuration lock is poisoned
§Errors
Returns an error if:
- The configuration lock is poisoned (indicating a panic occurred while another thread held the lock)
§Behavior
Internally, read_lock() performs the following operations:
- Calls
Config::get_instance()to obtain a reference to the global configuration singleton - Attempts to acquire a read lock using
RwLock::read() - Maps any lock poisoning error to a boxed error type for consistency
The read lock allows multiple threads to concurrently read configuration data while preventing any thread from acquiring a write lock until all read locks are released.
§Side Effects
- Acquires a read lock on the global configuration, potentially blocking write operations until the guard is dropped
- No modifications are made to the configuration data
§Usage Pattern
use aimx::Config;
// Acquire read access to configuration
let config_guard = Config::read_lock().expect("Failed to acquire config read lock");
// Read configuration values
let workspace_path = &config_guard.workspace_path;
let fast_provider = &config_guard.fast;
// Configuration is automatically released when guard goes out of scope§See Also
Config::write_lock()- Acquires write access to the configurationConfig::get_instance()- Returns a reference to the global configuration singletonRwLockReadGuard- The standard library read guard type
Sourcepub fn write_lock() -> Result<RwLockWriteGuard<'static, Self>, Box<dyn Error>>
pub fn write_lock() -> Result<RwLockWriteGuard<'static, Self>, Box<dyn Error>>
§Acquire a write guard for the global config.
§title: Write Lock
Acquires exclusive write access to the global configuration singleton, providing thread-safe access for modifying configuration data.
§Returns
Returns a Result<RwLockWriteGuard<'static, Config>> containing:
Ok(guard)- A write guard that provides mutable access to the configurationErr(error)- An error if the configuration lock is poisoned
§Errors
Returns an error if:
- The configuration lock is poisoned (indicating a panic occurred while another thread held the lock)
§Behavior
Internally, write_lock() performs the following operations:
- Calls
Config::get_instance()to obtain a reference to the global configuration singleton - Attempts to acquire a write lock using
RwLock::write() - Maps any lock poisoning error to a boxed error type for consistency
The write lock provides exclusive access to the configuration, preventing any other thread from reading or writing until the lock is released.
§Side Effects
- Acquires an exclusive write lock on the global configuration, blocking all other read and write operations until the guard is dropped
- Allows modification of configuration data through the returned guard
§Usage Pattern
use aimx::Config;
// Acquire write access to configuration
let mut config_guard = Config::write_lock().expect("Failed to acquire config write lock");
// Modify configuration values
config_guard.workspace_path = "/new/workspace/path".to_string();
config_guard.fast.model = "llama3:8b".to_string();
config_guard.standard.url = "https://api.openai.com/v1".to_string();
// Persist changes to disk
config_guard.save().expect("Failed to save configuration");
// Configuration is automatically released when guard goes out of scopeFor conditional updates based on current configuration:
use aimx::Config;
let mut config_guard = Config::write_lock().expect("Failed to acquire write lock");
// Check current value before updating
if config_guard.workspace_path.is_empty() {
config_guard.workspace_path = "/default/workspace".to_string();
}
// Update provider settings
config_guard.fast.model = "mistral:latest".to_string();
config_guard.fast.temperature = 0.3;
// Save changes
config_guard.save().expect("Failed to save configuration");§File Operations
Configuration modifications require explicit persistence:
- In-Memory Changes: Modifications through the write guard only affect memory
- Persistence Required: Call
config_guard.save()to write changes to disk - Atomic Updates: The entire configuration is written as a single TOML file
- Error Handling: Save operations can fail due to file system issues
§MVCC Considerations
The configuration uses a reader-writer lock pattern:
- Exclusive Access: Write lock prevents all concurrent read and write operations
- Lock Poisoning: If a writer panics, the lock becomes poisoned and returns errors
- Guard Lifetime: Keep the write guard for minimal duration to avoid blocking readers
- Deadlock Prevention: Cannot acquire read lock while holding write lock
§Performance Considerations
- Blocking: Write lock blocks all other configuration access
- Minimal Duration: Keep write operations brief to minimize blocking
- Batch Changes: Group multiple configuration changes in a single write lock
- Avoid Nested Locks: Do not perform I/O or other blocking operations while holding the lock
§Error Handling
Handle lock poisoning and save errors appropriately:
use aimx::Config;
match Config::write_lock() {
Ok(mut config_guard) => {
// Modify configuration
config_guard.workspace_path = "/new/path".to_string();
// Save changes with error handling
match config_guard.save() {
Ok(()) => println!("Configuration saved successfully"),
Err(e) => {
eprintln!("Failed to save configuration: {}", e);
// Configuration changes are lost if save fails
}
}
}
Err(e) => {
eprintln!("Failed to acquire write lock: {}", e);
// Configuration lock may be poisoned
}
}§See Also
Config::read_lock()- Acquires read-only access to the configurationConfig::get_instance()- Returns a reference to the global configuration singletonConfig::save()- Persist configuration changes to diskConfig::path()- Determine configuration file locationRwLockWriteGuard- The standard library write guard type
Sourcepub fn new() -> Result<Self, Box<dyn Error>>
pub fn new() -> Result<Self, Box<dyn Error>>
§Load existing configuration or create and persist defaults.
§title: Config new
This function loads the application configuration from disk, or creates and persists a default configuration if none exists.
§Returns
Returns a Config instance containing the loaded configuration data, or a default configuration if no config file was found.
§Errors
Returns an error if:
- A configuration file exists but cannot be read from disk
- A configuration file exists but contains invalid TOML syntax
- A configuration file exists but cannot be deserialized into the
Configstructure - The default configuration cannot be saved to disk
§Behavior
Internally, new() performs the following operations:
- Attempts to load an existing configuration file from the platform-specific config directory
- If loading succeeds, returns the loaded configuration
- If loading fails (file doesn’t exist or is invalid), creates a default configuration using
Config::default() - Saves the default configuration to disk for future use
- Returns the default configuration
§Side Effects
- Creates the platform-specific configuration directory if it doesn’t exist
- Creates a default configuration file at the platform-specific path if no config exists
- Persists default provider settings for all inference model types (fast, standard, thinking, extract, instruct, coder)
§Usage Pattern
use aimx::config::Config;
// Load or create default configuration
let config = Config::new().expect("Failed to load configuration");
// Use configuration settings
println!("Workspace path: {}", config.workspace_path);§See Also
Config::load()- Load configuration without creating defaultsConfig::save()- Save configuration to diskConfig::default()- Create default configuration valuesConfig::path()- Get the configuration file pathAppName::set()- Set custom application name for config resolution
Sourcepub fn load() -> Result<Self, Box<dyn Error>>
pub fn load() -> Result<Self, Box<dyn Error>>
§Load configuration from disk.
§title: Load configuration
Loads the AIMX application configuration from a TOML file stored in the platform-specific configuration directory.
The configuration file is automatically located based on the current application name (set via AppName::set or defaulting to “aimx”) and the user’s operating system conventions for configuration storage.
§Returns
Returns a Config containing the loaded configuration values if successful, or an error if the file cannot be read or parsed.
§Errors
Returns an error if:
- The platform-specific configuration directory cannot be determined
- The configuration file does not exist at the expected path
- The configuration file cannot be read due to permissions or I/O issues
- The file content is not valid TOML format
- The TOML content cannot be deserialized into the
Configstructure
§Behavior
Internally, load() performs the following operations:
- Resolves the configuration file path using
Config::path() - Reads the entire file content as a UTF-8 string
- Parses the TOML content using
toml::from_str() - Returns the deserialized
Configinstance
§Usage Pattern
use aimx::Config;
// Load configuration (typically done during application startup)
match Config::load() {
Ok(config) => {
println!("Loaded workspace path: {}", config.workspace_path);
println!("Fast model: {}", config.fast.model);
// Use the configuration...
}
Err(error) => {
eprintln!("Failed to load configuration: {}", error);
// Handle the error or fall back to defaults
}
}§File Operations
- Reads from the configuration file in the platform-specific config directory
- File path format:
{config_dir}/{app_name}.toml - Example paths:
- Linux:
~/.config/aimx/aimx.toml - macOS:
~/Library/Application Support/aimx/aimx.toml - Windows:
%APPDATA%\aimx\aimx.toml
- Linux:
§See Also
Config::new()- Creates or loads configuration with fallback to defaultsConfig::save()- Persists configuration to diskConfig::path()- Determines the configuration file pathAppName::set()- Sets the application name for configuration resolution
Sourcepub fn save(&self) -> Result<(), Box<dyn Error>>
pub fn save(&self) -> Result<(), Box<dyn Error>>
§Persist configuration to disk.
§title: Save configuration
Persists the AIMX application configuration to a TOML file in the platform-specific configuration directory.
The configuration is saved with human-readable formatting using toml::to_string_pretty(), making it easy to read and edit manually if needed. The function automatically creates the configuration directory if it doesn’t already exist.
§Returns
Returns Ok(()) if the configuration was successfully saved to disk, or an error if the operation failed.
§Errors
Returns an error if:
- The platform-specific configuration directory cannot be determined
- The configuration directory cannot be created due to permissions or I/O issues
- The configuration cannot be serialized to TOML format
- The TOML content cannot be written to the configuration file
§Behavior
Internally, save() performs the following operations:
- Resolves the configuration file path using
Config::path() - Ensures the parent directory exists by creating it if necessary
- Serializes the configuration to pretty-printed TOML format using
toml::to_string_pretty() - Writes the TOML content to the configuration file
§Side Effects
- Creates the platform-specific configuration directory if it doesn’t exist
- Overwrites any existing configuration file at the target path
- File path format:
{config_dir}/{app_name}.toml - Example paths:
- Linux:
~/.config/aimx/aimx.toml - macOS:
~/Library/Application Support/aimx/aimx.toml - Windows:
%APPDATA%\aimx\aimx.toml
- Linux:
§Usage Pattern
use aimx::Config;
use std::sync::Arc;
// Acquire write access to modify configuration
let mut config = Config::write_lock().expect("Failed to acquire config lock");
// Make changes to the configuration
config.workspace_path = "/my/workspace".to_string();
config.fast.model = "llama2:latest".to_string();
// Persist changes to disk
match config.save() {
Ok(()) => println!("Configuration saved successfully"),
Err(error) => eprintln!("Failed to save configuration: {}", error),
}
// Lock is automatically released when `config` goes out of scope§File Operations
This function performs write operations that modify the configuration file on disk. The operation is atomic at the file level - either the entire configuration is written successfully or the file remains unchanged if an error occurs during writing.
§See Also
Config::load()- Loads configuration from diskConfig::new()- Creates or loads configuration with fallback to defaultsConfig::path()- Determines the configuration file pathConfig::write_lock()- Acquires exclusive write access to configurationAppName::set()- Sets the application name for configuration resolution
Sourcepub fn path() -> Result<PathBuf, Box<dyn Error>>
pub fn path() -> Result<PathBuf, Box<dyn Error>>
§Platform-specific configuration file path.
§title: Get Config Path
This function returns the platform-specific file path where the AIMX configuration file should be stored and loaded from.
The configuration path is determined using the directories crate, which follows platform conventions:
- Linux:
$HOME/.config/{app_name}/ - macOS:
$HOME/Library/Application Support/{app_name}/ - Windows:
{FOLDERID_RoamingAppData}\{app_name}\
The configuration file itself is named {app_name}.toml where {app_name} is obtained from AppName::get().
§Arguments
This function takes no arguments.
§Returns
Returns a Result<PathBuf> containing the full path to the configuration file, including the filename.
§Errors
Returns an error if:
- The system’s project directories cannot be determined (rare, typically only in severely misconfigured environments)
§Behavior
Internally, get_config_path() performs the following operations:
- Retrieves the application name using
AppName::get() - Uses [
ProjectDirs::from()] to determine platform-specific directory paths - Constructs the final path by joining the config directory with the filename
{app_name}.toml
§File Operations
This function only calculates a file path - it does not perform any file I/O operations. The returned path can be used with standard file operations like reading, writing, or checking file existence.
§Usage Pattern
use aimx::config::Config;
use std::path::PathBuf;
// Get the configuration file path
let config_path: PathBuf = Config::path()
.expect("Failed to determine config path");
// Check if config file exists
if config_path.exists() {
println!("Config file exists at: {:?}", config_path);
} else {
println!("Config file will be created at: {:?}", config_path);
}§See Also
Config::load()- Load configuration from the path returned by this functionConfig::save()- Save configuration to the path returned by this functionAppName::get()- Get the application name used in path construction- [
ProjectDirs] - The underlying crate used for platform-specific directory resolution
Sourcepub fn get_provider(&self, model: &Model) -> &Provider
pub fn get_provider(&self, model: &Model) -> &Provider
§Provider configuration for the requested model class.
§title: Get Provider
This function retrieves the configuration for a specific inference model provider from the global configuration.
§Arguments
model- A reference to aModelenum value specifying which model configuration to retrieve. The supported model types are:Model::Fast- Fast model optimized for speed and low latencyModel::Standard- Standard model for balanced general-purpose useModel::Thinking- Thinking model optimized for complex reasoningModel::Extract- Extraction model optimized for large context windowsModel::Instruct- Instruct model optimized for following instructionsModel::Coder- Coder model optimized for programming tasks
§Returns
Returns a reference to a Provider configuration containing the API settings, model identifier, and runtime parameters for the requested model type.
§Behavior
The function performs a simple pattern match on the provided model enum and returns the corresponding provider configuration field from the Config struct. This provides type-safe access to model-specific provider settings.
§Usage Pattern
use aimx::{get_config, inference::{Model, Provider}};
// Get a read lock on the global configuration
let config_guard = get_config().unwrap();
// Retrieve the provider configuration for the 'fast' model
let fast_provider: &Provider = config_guard.get_provider(&Model::Fast);
// Access provider settings
println!("Fast model: {}", fast_provider.model);
println!("API: {}", fast_provider.api);§See Also
Config- The main configuration struct containing all provider settingsProvider- Provider configuration containing API settings and model parametersModel- Model type enum defining different inference model categoriesget_config()- Function to access the global configuration singleton