///|
/// Compare JSON values for sorting
fn compare_json(a : Json, b : Json) -> Int {
match (a, b) {
(Null, Null) => 0
(Null, _) => -1
(_, Null) => 1
(False, False) => 0
(False, True) => -1
(True, False) => 1
(True, True) => 0
(Number(x, ..), Number(y, ..)) => x.compare(y)
(String(x), String(y)) => x.compare(y)
(Array(x), Array(y)) => compare_array_view(x, y)
// Type ordering: null < bool < number < string < array < object
(False | True, Number(_)) => -1
(Number(_), False | True) => 1
(Number(_), String(_)) => -1
(String(_), Number(_)) => 1
(String(_), Array(_)) => -1
(Array(_), String(_)) => 1
(Array(_), Object(_)) => -1
(Object(_), Array(_)) => 1
(Object(_), Object(_)) => 0 // Objects compare equal
_ => 0
}
}
///|
fn compare_array_view(a : ArrayView[Json], b : ArrayView[Json]) -> Int {
match (a, b) {
([], []) => 0
([], _) => -1
(_, []) => 1
([head_a, .. tail_a], [head_b, .. tail_b]) => {
let cmp = compare_json(head_a, head_b)
if cmp != 0 {
cmp
} else {
compare_array_view(tail_a, tail_b)
}
}
}
}