use std::cmp::Ordering;
use ciborium::Value as CborValue;
pub fn cbor_cmp(a: &CborValue, b: &CborValue) -> Ordering {
let (a, b) = (datetime_as_text(a), datetime_as_text(b));
match (a, b) {
(CborValue::Integer(l), CborValue::Integer(r)) => i128::from(*l).cmp(&i128::from(*r)),
(CborValue::Text(l), CborValue::Text(r)) => l.cmp(r),
(CborValue::Bool(l), CborValue::Bool(r)) => l.cmp(r),
_ => match (number(a), number(b)) {
(Some(l), Some(r)) => l.total_cmp(&r),
_ => format!("{a:?}").cmp(&format!("{b:?}")),
},
}
}
pub(super) fn datetime_as_text(value: &CborValue) -> &CborValue {
match value {
CborValue::Tag(0, inner) if matches!(inner.as_ref(), CborValue::Text(_)) => inner,
_ => value,
}
}
fn number(value: &CborValue) -> Option<f64> {
let n = match value {
CborValue::Integer(i) => i128::from(*i) as f64,
CborValue::Float(f) => *f,
_ => return None,
};
Some(if n == 0.0 { 0.0 } else { n })
}