serde_json_merge 0.0.7

Merge, index, iterate, and sort a serde_json::Value (recursively)
//! Sorting operations for JSON object keys and array values.

pub mod keys;
pub mod sortable_value;
pub mod values;

use super::index::Path as IndexPath;
use super::iter::{Iter, Traverser, dfs::Dfs};
pub use keys::Sort as Keys;
use serde_json::Value;
pub use sortable_value::Ord as ValueOrd;
pub use values::Sort as Values;

/// Compares values while preserving traversal order.
pub trait PartialEqOrdered {
    /// Compares values and their paths in traversal order.
    fn eq(&self, other: &Self) -> bool;
}

impl PartialEqOrdered for Value {
    fn eq(&self, other: &Self) -> bool {
        let entries = self.iter_recursive::<Dfs>();
        let other_entries = other.iter_recursive::<Dfs>();
        entries.into_iter().eq(other_entries)
    }
}

impl PartialEqOrdered for &Value {
    fn eq(&self, other: &Self) -> bool {
        PartialEqOrdered::eq(*self, *other)
    }
}

/// Sorts object keys and array values.
pub trait Sort: Keys + Values {
    /// Sorts keys and values in place.
    #[inline]
    fn sort(&mut self) {
        self.sort_keys();
        self.sort_values();
    }

    /// Recursively sorts keys and values in place.
    #[inline]
    fn sort_recursive<T>(&mut self)
    where
        T: Traverser,
    {
        self.sort_keys_recursive::<T>();
        self.sort_values_recursive::<T>();
    }

    /// Sorts keys and values in place using unstable ordering.
    #[inline]
    fn sort_unstable(&mut self) {
        self.sort_keys_unstable();
        self.sort_values_unstable();
    }

    /// Recursively sorts keys and values in place using unstable ordering.
    #[inline]
    fn sort_unstable_recursive<T>(&mut self)
    where
        T: Traverser,
    {
        self.sort_keys_unstable_recursive::<T>();
        self.sort_values_unstable_recursive::<T>();
    }

    /// Returns the sorted value.
    #[inline]
    #[must_use]
    fn sorted(mut self) -> Self {
        self.sort();
        self
    }

    /// Returns the recursively sorted value.
    #[inline]
    #[must_use]
    fn sorted_recursive<T>(mut self) -> Self
    where
        T: Traverser,
    {
        self.sort_recursive::<T>();
        self
    }

    /// Returns the unstably sorted value.
    #[inline]
    #[must_use]
    fn sorted_unstable(mut self) -> Self {
        self.sort_unstable();
        self
    }

    /// Returns the recursively unstably sorted value.
    #[inline]
    #[must_use]
    fn sorted_unstable_recursive<T>(mut self) -> Self
    where
        T: Traverser,
    {
        self.sort_unstable_recursive::<T>();
        self
    }
}

impl Sort for Value {}

#[cfg(test)]
mod test {

    #[cfg(feature = "preserve_order")]
    #[test]
    fn preserves_order() {
        use crate::test::{assert_eq_ordered, assert_ne_ordered};
        use serde_json::json;

        let value = json!({
            "b": "b",
            "a": "a",
            "d": { "1": "1", "2": "2" },
            "c": "c",
        });
        assert_ne_ordered!(
            &value,
            &json!({
                "a": "a",
                "b": "b",
                "c": "c",
                "d": { "1": "1", "2": "2" },
            })
        );
        assert_ne_ordered!(
            &value,
            &json!({
                "b": "b",
                "a": "a",
                "d": { "2": "2", "1": "1" },
                "c": "c",
            })
        );
        assert_eq_ordered!(&value, &value,);
    }
}