Config

Struct Config 

Source
pub struct Config {
    pub logging: LoggingConfig,
    pub database: DatabaseConfig,
    pub paths: PathsConfig,
}
Expand description

Main configuration structure

Fields§

§logging: LoggingConfig

Logging settings

§database: DatabaseConfig

Database settings

§paths: PathsConfig

Path settings

Implementations§

Source§

impl Config

Source

pub fn get_nuanalytics_dir() -> PathBuf

Get the $NU_ANALYTICS directory path

Returns:

  • Linux: ~/.config/nuanalytics
  • macOS: ~/Library/Application Support/nuanalytics
  • Windows: %APPDATA%\nuanalytics
Source

pub fn merge_defaults(&mut self, defaults: &Self) -> bool

Merge missing fields from defaults into this config

This method is used when loading configuration to ensure that newly added configuration fields are populated with their default values. Only fields that are empty in the current config and non-empty in defaults are updated.

§Returns

true if any fields were added/changed, false otherwise

§Examples
let mut config = Config::from_toml(old_config_str)?;
let defaults = Config::from_defaults();
if config.merge_defaults(&defaults) {
    // Config was updated with new fields
    config.save()?;
}
Source

pub fn apply_overrides(&mut self, overrides: &ConfigOverrides)

Apply CLI-provided overrides onto the loaded configuration

This allows command-line arguments to override configuration file values without modifying the persistent configuration file. Only non-None values in the overrides struct will replace config values.

§Arguments
  • overrides - A ConfigOverrides struct with optional override values
§Examples
let mut config = Config::load();
let overrides = ConfigOverrides {
    level: Some("debug".to_string()),
    ..Default::default()
};
config.apply_overrides(&overrides);
// config.logging.level is now "debug" for this run only
Source

pub fn get_config_file_path() -> PathBuf

Get the user config file path

Returns the full path to the configuration file:

  • config.toml for release builds
  • dconfig.toml for debug builds (allows separate debug config)

The file is located in the directory returned by get_nuanalytics_dir.

Source

pub fn from_toml(toml_str: &str) -> Result<Self, Error>

Initialize config from a TOML string

Parses a TOML configuration string and expands any $NU_ANALYTICS variables in the values. Missing fields will use their serde defaults (typically empty strings or false).

§Arguments
  • toml_str - A TOML-formatted configuration string
§Errors

Returns an error if the TOML cannot be parsed or doesn’t match the expected schema

§Examples
let config = Config::from_toml(r#"
[Logging]
level = "info"
file = "$NU_ANALYTICS/app.log"
"#)?;
Source

pub fn from_defaults() -> Self

Load configuration from embedded defaults

Loads the compiled-in default configuration that is bundled with the binary. The defaults differ between debug and release builds:

  • Debug: Uses DefaultCLIConfigDebug.toml
  • Release: Uses DefaultCLIConfigRelease.toml
§Returns

A Config instance with all values set to their defaults.

§Panics

Panics if the embedded default configuration is invalid TOML or cannot be parsed. This should never happen in practice since the defaults are compiled into the binary.

§Examples
let config = Config::from_defaults();
assert_eq!(config.logging.level, "info");
Source

pub fn load() -> Self

Load configuration from file, or create from defaults if not found

This is the primary way to load configuration. It handles several scenarios:

  • If config file exists: Loads from file, merges missing fields from defaults, saves updated config
  • If config file doesn’t exist (first run): Creates config directory if needed, loads defaults, saves to file

The merge behavior ensures that upgrading the application automatically adds new config fields while preserving existing user settings.

§Returns

A Config instance loaded from file or defaults. Falls back to defaults if any error occurs during loading.

§Examples
let config = Config::load();
// Config is now loaded from ~/.config/nuanalytics/config.toml (or defaults if first run)
Source

pub fn save(&self) -> Result<(), Box<dyn Error>>

Save configuration to file

Serializes the current configuration to TOML format and writes it to the platform-specific config file. The config directory will be created if it doesn’t exist.

The saved file will use the format:

[Logging]
level = "info"
file = "$NU_ANALYTICS/logs/nuanalytics.log"
verbose = false

[Database]
token = "your-token"
endpoint = "https://api.example.com"

[Paths]
metrics_dir = "$NU_ANALYTICS/metrics"
reports_dir = "$NU_ANALYTICS/reports"
§Errors

Returns an error if:

  • The config cannot be serialized to TOML (shouldn’t happen)
  • The config directory cannot be created
  • The file cannot be written (permissions, disk full, etc.)
§Examples
let mut config = Config::load()?;
config.logging.level = "debug".to_string();
config.save()?;
Source

pub fn get(&self, key: &str) -> Option<String>

Get a configuration value by key

Retrieves a configuration value using a string key that maps to the config structure. Supports all config fields in the format section.field or just field for top-level fields.

Supported keys:

  • level: Logging level (“debug”, “info”, “warn”, “error”)
  • file: Log file path
  • verbose: Verbose logging boolean
  • token: Database authentication token
  • endpoint: Database API endpoint
  • metrics_dir: Metrics output directory path
  • reports_dir: Reports output directory path
§Arguments
  • key: The configuration key to retrieve
§Returns
  • Some(String): The configuration value as a string
  • None: If the key is not recognized
§Examples
let config = Config::load()?;
if let Some(level) = config.get("level") {
    println!("Current log level: {}", level);
}
Source

pub fn set(&mut self, key: &str, value: &str) -> Result<(), String>

Set a configuration value by key

Updates a configuration value using a string key and value. The value will be validated and converted to the appropriate type.

Supported keys and their value formats:

  • level: String (“debug”, “info”, “warn”, “error”, “trace”, “off”)
  • file: String (file path, can include $NU_ANALYTICS)
  • verbose: Boolean (“true” or “false”)
  • token: String (any value)
  • endpoint: String (typically a URL)
  • metrics_dir: String (directory path for metrics CSV files)
  • reports_dir: String (directory path for report files)

Note: This method updates the in-memory config. Call save() to persist changes.

§Arguments
  • key: The configuration key to set
  • value: The new value as a string
§Errors

Returns an error if:

  • The key is not recognized
  • The value cannot be parsed (e.g., “maybe” for verbose boolean)
§Examples
let mut config = Config::load()?;
config.set("level", "debug")?;
config.set("verbose", "true")?;
config.save()?;
Source

pub fn unset(&mut self, key: &str, defaults: &Self) -> Result<(), String>

Unset a configuration value by key (reset to default)

Resets a single configuration value to its default value. This is useful for reverting individual settings without losing all customizations.

The default value is taken from the provided defaults config (typically from from_defaults()).

Note: This method updates the in-memory config. Call save() to persist changes.

§Arguments
  • key: The configuration key to reset
  • defaults: A config instance containing default values
§Errors

Returns an error if the key is not recognized.

§Examples
let mut config = Config::load()?;
let defaults = Config::from_defaults();

config.set("level", "trace")?;
config.unset("level", &defaults)?;  // Resets to "info"
config.save()?;
Source

pub fn reset() -> Result<(), Error>

Reset all configuration to defaults

Deletes the configuration file, causing the next load() call to recreate it from defaults. This is a destructive operation that removes all user customizations.

If the config file doesn’t exist, this method succeeds without doing anything.

§Safety

This is a destructive operation. The CLI typically requires user confirmation before calling this method.

§Errors

Returns an error if:

  • The config file exists but cannot be deleted (permissions, file locked, etc.)
§Examples
// Typically preceded by user confirmation
Config::reset()?;
println!("Configuration reset to defaults");

// Next load will recreate from defaults
let config = Config::load()?;

Trait Implementations§

Source§

impl Clone for Config

Source§

fn clone(&self) -> Config

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Config

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Config

Source§

fn default() -> Config

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for Config

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Display for Config

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Serialize for Config

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl Freeze for Config

§

impl RefUnwindSafe for Config

§

impl Send for Config

§

impl Sync for Config

§

impl Unpin for Config

§

impl UnwindSafe for Config

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,