diff --git a/src/config/runtime.rs b/src/config/runtime.rs index 6b80019f..5fe969ff 100644 --- a/src/config/runtime.rs +++ b/src/config/runtime.rs @@ -14,6 +14,13 @@ pub struct Config { loggers: Vec, } +/// Any structs that impl this trait can be consumed by ConfigBuilder to make +/// build a config +pub trait ConfigBuildable { + /// Unwraps the stuct into structs the builder can build from + fn builder_unwrap(self) -> (Option, Root); +} + impl Config { /// Creates a new `ConfigBuilder`. pub fn builder() -> ConfigBuilder { @@ -53,6 +60,18 @@ impl Config { } } +impl ConfigBuildable for Config { + fn builder_unwrap(self) -> (Option, Root) { + ( + Some(ConfigBuilder { + appenders: self.appenders, + loggers: self.loggers, + }), + self.root, + ) + } +} + /// A builder for `Config`s. #[derive(Debug, Default)] pub struct ConfigBuilder { @@ -91,6 +110,11 @@ impl ConfigBuilder { self } + /// Consumes two `ConfigBuilders` and combines them into one + pub fn combine(self, ConfigBuilder { appenders, loggers }: ConfigBuilder) -> ConfigBuilder { + self.appenders(appenders).loggers(loggers) + } + /// Consumes the `ConfigBuilder`, returning the `Config`. /// /// Unlike `build`, this method will always return a `Config` by stripping @@ -156,8 +180,16 @@ impl ConfigBuilder { } /// Consumes the `ConfigBuilder`, returning the `Config`. - pub fn build(self, root: Root) -> Result { - let (config, errors) = self.build_lossy(root); + pub fn build(self, buildable: impl ConfigBuildable) -> Result { + let (config_builder, root) = buildable.builder_unwrap(); + + let (config, errors) = if let Some(config_builder) = config_builder { + self.combine(config_builder) + } else { + self + } + .build_lossy(root); + if errors.is_empty() { Ok(config) } else { @@ -195,6 +227,12 @@ impl Root { } } +impl ConfigBuildable for Root { + fn builder_unwrap(self) -> (Option, Root) { + (None, self) + } +} + /// A builder for `Root`s. #[derive(Clone, Eq, PartialEq, Hash, Debug)] pub struct RootBuilder {