Skip to main content

config/
root.rs

1use crate::{Configuration, ConfigurationProvider, LoadError};
2use std::fmt::{Debug, Formatter, Result as FormatResult};
3use std::{borrow::Borrow, ops::Deref};
4
5/// Defines the possible reload errors.
6#[derive(PartialEq, Clone)]
7pub enum ReloadError {
8    /// Indicates one or more provider load errors occurred.
9    Provider(Vec<(String, LoadError)>),
10
11    /// Indicates reload cannot be performed because there
12    /// are borrowed references. The number of references
13    /// may be reported if known.
14    Borrowed(Option<usize>),
15}
16
17impl Debug for ReloadError {
18    fn fmt(&self, f: &mut Formatter<'_>) -> FormatResult {
19        match self {
20            Self::Provider(errors) => {
21                if errors.len() == 1 {
22                    write!(f, "{} ({})", errors[0].1.message(), &errors[0].0)?;
23                } else {
24                    f.write_str("One or more load errors occurred:")?;
25
26                    for (i, (provider, error)) in errors.iter().enumerate() {
27                        write!(f, "\n  [{}]: {} ({})", (i + 1), error.message(), provider)?;
28                    }
29                }
30            }
31            Self::Borrowed(count) => {
32                write!(f, "Reload failed because the are")?;
33
34                if let Some(value) = count {
35                    write!(f, "{} ", value)?;
36                }
37
38                write!(f, " outstanding borrow references.")?;
39            }
40        }
41
42        Ok(())
43    }
44}
45
46/// Represents a configuration reload result.
47pub type ReloadResult = std::result::Result<(), ReloadError>;
48
49/// Represents the root of a [`Configuration`](crate::Configuration) hierarchy.
50pub trait ConfigurationRoot:
51    Configuration + AsRef<dyn Configuration> + Borrow<dyn Configuration> + Deref<Target = dyn Configuration> + Debug
52{
53    /// Force the configuration values to be reloaded from the underlying
54    /// [`ConfigurationProvider`](crate::ConfigurationProvider) collection.
55    fn reload(&mut self) -> ReloadResult;
56
57    /// Gets the [`ConfigurationProvider`](crate::ConfigurationProvider) sequence for this configuration.
58    fn providers(&self) -> Box<dyn ConfigurationProviderIterator<'_> + '_>;
59
60    /// Converts the [`ConfigurationRoot`] into a [`Configuration`](crate::Configuration).
61    fn as_config(&self) -> Box<dyn Configuration>;
62}
63
64/// Defines the behavior of an iterator over a
65/// [`ConfigurationProvider`](crate::ConfigurationProvider) set.
66pub trait ConfigurationProviderIterator<'a>:
67    Iterator<Item = Box<dyn ConfigurationProvider + 'a>>
68    + ExactSizeIterator<Item = Box<dyn ConfigurationProvider + 'a>>
69    + DoubleEndedIterator<Item = Box<dyn ConfigurationProvider + 'a>>
70{
71}