use crate::IndexPath;
use crate::iter::{KeyValueIter, Traverser};
use serde_json::Value;
#[cfg(feature = "sort")]
use std::fmt;
pub trait ValueExt {
fn try_keys(&self) -> Option<Vec<String>>;
}
impl ValueExt for Option<&Value> {
fn try_keys(&self) -> Option<Vec<String>> {
self.and_then(|value| match value {
Value::Object(map) => Some(map.keys().cloned().collect::<Vec<String>>()),
_ => None,
})
}
}
pub trait CollectCloned {
fn collect_cloned(self) -> Vec<(IndexPath, Value)>;
}
impl<'a, Iter, T> CollectCloned for Iter
where
Iter: IntoIterator<IntoIter = KeyValueIter<'a, T>>,
T: Traverser + Clone,
{
fn collect_cloned(self) -> Vec<(IndexPath, Value)> {
self.into_iter()
.map(|(index, value)| (index, value.clone()))
.collect::<Vec<(IndexPath, Value)>>()
}
}
#[cfg(feature = "sort")]
#[allow(
clippy::panic,
reason = "test assertion helper that is designed to panic on failure"
)]
pub fn assert_failed(
left: &dyn fmt::Debug,
op: &str,
right: &dyn fmt::Debug,
args: Option<fmt::Arguments<'_>>,
) -> ! {
match args {
Some(args) => panic!(
r"assertion failed: `(left {op} right)`
left: `{left:?}`,
right: `{right:?}`: {args:?}"
),
None => panic!(
r"assertion failed: `(left {op} right)`
left: `{left:?}`,
right: `{right:?}`"
),
}
}
#[cfg(feature = "sort")]
macro_rules! assert_eq_ordered {
($left:expr, $right:expr $(,)?) => {
match (&$left, &$right) {
(left_val, right_val) => {
if !$crate::sort::PartialEqOrdered::eq(left_val, right_val) {
$crate::test::assert_failed(
left_val,
"equals (ordered)",
right_val,
std::option::Option::None
);
}
}
}
};
($left:expr, $right:expr, $($arg:tt)+) => {
match (&$left, &$right) {
(left_val, right_val) => {
if !$crate::sort::PartialEqOrdered::eq(left_val, right_val) {
$crate::test::assert_failed(
left_val,
"equals (ordered)",
right_val,
std::option::Option::Some(std::format_args!($($arg)+))
);
}
}
}
};
}
#[cfg(feature = "sort")]
pub(crate) use assert_eq_ordered;
#[cfg(all(feature = "sort", feature = "preserve_order"))]
macro_rules! assert_ne_ordered {
($left:expr, $right:expr $(,)?) => {
match (&$left, &$right) {
(left_val, right_val) => {
if $crate::sort::PartialEqOrdered::eq(left_val, right_val) {
$crate::test::assert_failed(
left_val,
"does not equal (ordered)",
right_val,
std::option::Option::None
);
}
}
}
};
($left:expr, $right:expr, $($arg:tt)+) => {
match (&$left, &$right) {
(left_val, right_val) => {
if $crate::sort::PartialEqOrdered::eq(left_val, right_val) {
$crate::test::assert_failed(
left_val,
"does not equal (ordered)",
right_val,
std::option::Option::Some(std::format_args!($($arg)+))
);
}
}
}
}
}
#[cfg(all(feature = "sort", feature = "preserve_order"))]
pub(crate) use assert_ne_ordered;