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
52    + AsRef<dyn Configuration>
53    + Borrow<dyn Configuration>
54    + Deref<Target = dyn Configuration>
55    + Debug
56{
57    /// Force the configuration values to be reloaded from the underlying
58    /// [`ConfigurationProvider`](crate::ConfigurationProvider) collection.
59    fn reload(&mut self) -> ReloadResult;
60
61    /// Gets the [`ConfigurationProvider`](crate::ConfigurationProvider) sequence for this configuration.
62    fn providers(&self) -> Box<dyn ConfigurationProviderIterator + '_>;
63
64    /// Converts the [`ConfigurationRoot`] into a [`Configuration`](crate::Configuration).
65    fn as_config(&self) -> Box<dyn Configuration>;
66}
67
68/// Defines the behavior of an iterator over a
69/// [`ConfigurationProvider`](crate::ConfigurationProvider) set.
70pub trait ConfigurationProviderIterator<'a>:
71    Iterator<Item = Box<dyn ConfigurationProvider + 'a>>
72    + ExactSizeIterator<Item = Box<dyn ConfigurationProvider + 'a>>
73    + DoubleEndedIterator<Item = Box<dyn ConfigurationProvider + 'a>>
74{
75}