config/
provider.rs

1use std::fmt::{Debug, Formatter, Result as FormatResult};
2use std::{any::type_name, path::PathBuf};
3use tokens::{ChangeToken, NeverChangeToken};
4
5use crate::Value;
6
7/// Defines the possible load errors.
8#[derive(PartialEq, Clone)]
9pub enum LoadError {
10    /// Indicates a generic load error with an error message.
11    Generic(String),
12
13    /// Indicates a file load error.
14    File {
15        /// Gets the error message.
16        message: String,
17
18        /// Gets the path of the file being loaded.
19        path: PathBuf,
20    },
21}
22
23impl LoadError {
24    /// Gets the load error message.
25    pub fn message(&self) -> &str {
26        match self {
27            Self::Generic(message) => message,
28            Self::File { message, .. } => message,
29        }
30    }
31}
32
33impl Debug for LoadError {
34    fn fmt(&self, f: &mut Formatter<'_>) -> FormatResult {
35        match self {
36            Self::Generic(message) => f.write_str(message),
37            Self::File { message, .. } => f.write_str(message),
38        }
39    }
40}
41
42/// Represents a configuration load result.
43pub type LoadResult = std::result::Result<(), LoadError>;
44
45/// Defines the behavior of an object that provides configuration key/values for an application.
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}