mirror of
https://github.com/OMGeeky/confique.git
synced 2026-01-23 03:38:51 +01:00
Add Builder type as convenient high level loading API
This commit is contained in:
@@ -41,13 +41,13 @@ fn main() -> Result<(), anyhow::Error> {
|
||||
print!("{}", confique::toml::format::<Conf>(FormatOptions::default()));
|
||||
println!("--------------------------------------------------------");
|
||||
|
||||
// let r = Conf::from_sources(&[
|
||||
// &Path::new("examples/files/simple.toml"),
|
||||
// &Path::new("examples/files/etc/simple.yaml"),
|
||||
// ])?;
|
||||
let r = Conf::builder()
|
||||
.file("examples/files/simple.toml")
|
||||
.file("examples/files/etc/simple.yaml")
|
||||
.load()?;
|
||||
|
||||
// println!();
|
||||
// println!("LOADED CONFIGURATION: {:#?}", r);
|
||||
println!();
|
||||
println!("LOADED CONFIGURATION: {:#?}", r);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
62
src/builder.rs
Normal file
62
src/builder.rs
Normal file
@@ -0,0 +1,62 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::{Config, Error, File, Partial};
|
||||
|
||||
|
||||
/// Convenience builder to configure, load and merge multiple configuration
|
||||
/// sources.
|
||||
///
|
||||
/// **Sources specified earlier have a higher priority**. Obtained via
|
||||
/// [`Config::builder`].
|
||||
pub struct Builder<C: Config> {
|
||||
sources: Vec<Source<C>>,
|
||||
}
|
||||
|
||||
impl<C: Config> Builder<C> {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self {
|
||||
sources: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds a configuration file as source. Infers the format from the file
|
||||
/// extension. If the path has no file extension or the extension is
|
||||
/// unknown, [`Builder::load`] will return an error.
|
||||
///
|
||||
/// The file is not considered required: if the file does not exist, an
|
||||
/// empty configuration (`C::Partial::empty()`) is used for this layer.
|
||||
pub fn file(mut self, path: impl Into<PathBuf>) -> Self {
|
||||
self.sources.push(Source::File(path.into()));
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds an already loaded partial configuration as source.
|
||||
pub fn preloaded(mut self, partial: C::Partial) -> Self {
|
||||
self.sources.push(Source::Preloaded(partial));
|
||||
self
|
||||
}
|
||||
|
||||
/// Loads all configured sources in order. Earlier sources have a higher
|
||||
/// priority, later sources only fill potential gaps.
|
||||
///
|
||||
/// Will return an error if loading the sources fails or if the merged
|
||||
/// configuration does not specify all required values.
|
||||
pub fn load(self) -> Result<C, Error> {
|
||||
let mut partial = C::Partial::empty();
|
||||
for source in self.sources {
|
||||
let layer = match source {
|
||||
Source::File(path) => File::new(path)?.load()?,
|
||||
Source::Preloaded(p) => p,
|
||||
};
|
||||
|
||||
partial = partial.with_fallback(layer);
|
||||
}
|
||||
|
||||
C::from_partial(partial.with_fallback(C::Partial::default_values()))
|
||||
}
|
||||
}
|
||||
|
||||
enum Source<C: Config> {
|
||||
File(PathBuf),
|
||||
Preloaded(C::Partial),
|
||||
}
|
||||
@@ -14,7 +14,7 @@ pub struct File {
|
||||
}
|
||||
|
||||
impl File {
|
||||
/// Configuration file with the given path. The format is inferred by the
|
||||
/// Configuration file with the given path. The format is inferred from the
|
||||
/// file extension. If the path does not have an extension or it is
|
||||
/// unknown, an error is returned.
|
||||
pub fn new(path: impl Into<PathBuf>) -> Result<Self, Error> {
|
||||
|
||||
13
src/lib.rs
13
src/lib.rs
@@ -3,6 +3,7 @@ use serde::Deserialize;
|
||||
#[doc(hidden)]
|
||||
pub mod internal;
|
||||
|
||||
mod builder;
|
||||
mod error;
|
||||
mod file;
|
||||
pub mod meta;
|
||||
@@ -14,6 +15,7 @@ pub mod toml;
|
||||
pub use serde;
|
||||
pub use confique_macro::Config;
|
||||
pub use self::{
|
||||
builder::Builder,
|
||||
error::Error,
|
||||
file::{File, FileFormat},
|
||||
};
|
||||
@@ -55,6 +57,17 @@ pub trait Config: Sized {
|
||||
/// If any required values are not defined in `partial`, an [`Error`] is
|
||||
/// returned.
|
||||
fn from_partial(partial: Self::Partial) -> Result<Self, Error>;
|
||||
|
||||
/// Convenience builder to configure, load and merge multiple configuration
|
||||
/// sources. **Sources specified earlier have a higher priority**; later
|
||||
/// sources only fill in the gaps. After all sources have been loaded, the
|
||||
/// default values (usually specified with `#[default = ...]`) are merged
|
||||
/// (with the lowest priority).
|
||||
///
|
||||
/// TODO: Example
|
||||
fn builder() -> Builder<Self> {
|
||||
Builder::new()
|
||||
}
|
||||
}
|
||||
|
||||
/// A potentially partial configuration object that can be directly deserialized
|
||||
|
||||
Reference in New Issue
Block a user