Skip to main content

kellnr_settings/
config_source.rs

1use std::collections::HashMap;
2
3use provcfg::Category;
4use serde::{Deserialize, Serialize};
5use utoipa::ToSchema;
6
7/// Represents the source of a configuration value.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
9#[serde(rename_all = "lowercase")]
10pub enum ConfigSource {
11    /// Value comes from compiled-in defaults
12    Default,
13    /// Value was set in a TOML configuration file
14    Toml,
15    /// Value was set via environment variable
16    Env,
17    /// Value was set via command-line argument
18    Cli,
19}
20
21/// Map provcfg's source categories onto kellnr's API-facing enum. kellnr only
22/// loads TOML files, so `Category::File` becomes `Toml`; `Category::Default`
23/// plus any future provcfg variants fall to `Default` via the wildcard arm.
24impl From<Category> for ConfigSource {
25    fn from(category: Category) -> Self {
26        match category {
27            Category::File => Self::Toml,
28            Category::Env => Self::Env,
29            Category::Cli => Self::Cli,
30            _ => Self::Default,
31        }
32    }
33}
34
35/// Maps setting keys (e.g., `"registry.data_dir"`) to their configuration source.
36///
37/// Built on demand by [`crate::settings::sources_from_prov`] from the
38/// `SettingsProv` produced by [`crate::settings::build_prov_with_cli`]. Keys
39/// not present in the map are treated as `Default` by every reader (see
40/// `crates/kellnr/src/config_printer.rs`), so it is not pre-populated.
41pub type SourceMap = HashMap<String, ConfigSource>;
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46
47    #[test]
48    fn config_source_serialization() {
49        assert_eq!(
50            serde_json::to_string(&ConfigSource::Default).unwrap(),
51            "\"default\""
52        );
53        assert_eq!(
54            serde_json::to_string(&ConfigSource::Toml).unwrap(),
55            "\"toml\""
56        );
57        assert_eq!(
58            serde_json::to_string(&ConfigSource::Env).unwrap(),
59            "\"env\""
60        );
61        assert_eq!(
62            serde_json::to_string(&ConfigSource::Cli).unwrap(),
63            "\"cli\""
64        );
65    }
66
67    #[test]
68    fn from_category_maps_file_env_cli_explicitly() {
69        assert_eq!(ConfigSource::from(Category::File), ConfigSource::Toml);
70        assert_eq!(ConfigSource::from(Category::Env), ConfigSource::Env);
71        assert_eq!(ConfigSource::from(Category::Cli), ConfigSource::Cli);
72    }
73
74    #[test]
75    fn from_category_falls_back_to_default_for_default_category() {
76        // The wildcard arm also catches any future `Category` variants provcfg
77        // may add, guarding the kellnr API against silent breakage.
78        assert_eq!(ConfigSource::from(Category::Default), ConfigSource::Default);
79    }
80}