Skip to main content

config/
provider.rs

1use crate::Value;
2use std::fmt::{Debug, Formatter, Result as FormatResult};
3use std::{any::type_name, path::PathBuf};
4use tokens::{ChangeToken, NeverChangeToken};
5
6/// Defines the possible load errors.
7#[derive(PartialEq, Clone)]
8pub enum LoadError {
9    /// Indicates a generic load error with an error message.
10    Generic(String),
11
12    /// Indicates a file load error.
13    File {
14        /// Gets the error message.
15        message: String,
16
17        /// Gets the path of the file being loaded.
18        path: PathBuf,
19    },
20}
21
22impl LoadError {
23    /// Gets the load error message.
24    pub fn message(&self) -> &str {
25        match self {
26            Self::Generic(message) => message,
27            Self::File { message, .. } => message,
28        }
29    }
30}
31
32impl Debug for LoadError {
33    fn fmt(&self, f: &mut Formatter<'_>) -> FormatResult {
34        match self {
35            Self::Generic(message) => f.write_str(message),
36            Self::File { message, .. } => f.write_str(message),
37        }
38    }
39}
40
41/// Represents a configuration load result.
42pub type LoadResult = std::result::Result<(), LoadError>;
43
44/// Defines the behavior of an object that provides configuration key/values for an application.
45#[cfg_attr(feature = "async", maybe_impl::traits(Send, Sync))]
46pub trait ConfigurationProvider {
47    /// Gets the name of the provider.
48    fn name(&self) -> &str {
49        type_name::<Self>()
50    }
51
52    /// Attempts to get a configuration value with the specified key.
53    ///
54    /// # Arguments
55    ///
56    /// * `key` - The key of the value to retrieve
57    fn get(&self, key: &str) -> Option<Value>;
58
59    /// Returns a [`ChangeToken`](tokens::ChangeToken) if this provider supports change tracking.
60    fn reload_token(&self) -> Box<dyn ChangeToken> {
61        Box::new(NeverChangeToken::new())
62    }
63
64    /// Loads the configuration values from the implemented source.
65    fn load(&mut self) -> LoadResult {
66        Ok(())
67    }
68
69    /// Gets the immediate descendent configuration keys for a given parent path based
70    /// on this [`ConfigurationProvider`] and the set of keys returned by all of the
71    /// preceding [`ConfigurationProvider`].
72    ///
73    /// # Arguments
74    ///
75    /// * `earlier_keys` - The sequence of keys returned by preceding provider for the same parent path
76    /// * `parent_path` - The optional parent path to evaluate
77    fn child_keys(&self, earlier_keys: &mut Vec<String>, parent_path: Option<&str>);
78}