schematic 0.20.2

A layered serde configuration and schema library.
Documentation
use crate::config::{MergeError, MergeResult, PartialConfig};

pub struct MergeManager<'a, Ctx> {
    context: &'a Ctx,
}

impl<'a, Ctx> MergeManager<'a, Ctx> {
    pub fn new(context: &'a Ctx) -> Self {
        Self { context }
    }

    pub fn apply<T>(self, prev: &mut Option<T>, next: Option<T>) -> Result<Self, MergeError> {
        self.apply_with(prev, next, crate::merge::replace)
    }

    pub fn apply_with<T>(
        self,
        prev: &mut Option<T>,
        next: Option<T>,
        merger: impl Fn(T, T, &Ctx) -> MergeResult<T>,
    ) -> Result<Self, MergeError> {
        let value = match (prev.take(), next) {
            (Some(prev), Some(next)) => merger(prev, next, self.context)?,
            (None, Some(next)) => Some(next),
            (other, None) => other,
        };

        if let Some(value) = value {
            prev.replace(value);
        }

        Ok(self)
    }

    pub fn nested<T: PartialConfig<Context = Ctx>>(
        self,
        prev: &mut Option<T>,
        next: Option<T>,
    ) -> Result<Self, MergeError> {
        self.apply_with(prev, next, |mut p, n, ctx| {
            p.merge(ctx, n)
                .map_err(|error| MergeError(error.to_string()))?;

            Ok(Some(p))
        })
    }
}