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}