1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
//! # Serde Merge
//!
//! `serde_merge` is a set of methods on top of [serde](https://github.com/serde-rs/serde)
//! for merging some serializable types.
use crate::error::Result;
use serde::{de::DeserializeOwned, Serialize};
pub mod error;
mod utils;
/// Alias for a `serde_json::Map<String, serde_json::Value>`.
///
/// Represents default type used in this library.
pub type Map = serde_json::Map<String, serde_json::Value>;
/// Merge two types into `serde_merge::Map`, returns `serde_merge::Result<serde_merge::Map>`.
///
/// Merge `R` into `L`. `R` override matching keys of `L`.
/// Both `L` and `R` have to implement `serde::Serialize`.
pub fn mmerge<L, R>(left: L, right: R) -> Result<Map>
where
L: Serialize,
R: Serialize,
{
let mut left_map = utils::to_map(&left)?;
let right_map = utils::to_map(&right)?;
left_map.extend(right_map);
Ok(left_map)
}
/// Merge two types into given type `T`, returns `serde_merge::Result<T>`. ( *Recommended* )
///
/// Works the same as `serde_merge::mmerge` but convert result to given type `T`.
/// `T` has to implement `serde::Serialize` and `serde::de::DeserializeOwned`.
pub fn tmerge<L, R, T>(left: L, right: R) -> Result<T>
where
L: Serialize,
R: Serialize,
T: Serialize + DeserializeOwned,
{
let merged_map = mmerge(left, right)?;
utils::from_map(&merged_map)
}
/// Merge two types into given type `T`, returns `serde_merge::Result<T>`. ( *Recommended* )
///
/// Works the same as `serde_merge::tmerge` except that `right`'s `Option::None` member
/// will not overwrite the corresponding value in `left`.
/// `T` has to implement `serde::Serialize` and `serde::de::DeserializeOwned`.
pub fn omerge<L, R, T>(left: L, right: R) -> Result<T>
where
L: Serialize,
R: Serialize,
T: Serialize + DeserializeOwned,
{
let mut left_map = utils::to_map(&left)?;
let mut right_map = utils::to_map(&right)?;
right_map.retain(|_, v| !v.is_null());
left_map.extend(right_map);
utils::from_map(&left_map)
}