0

Is it possible to sort JSON in rust language? If it is possible then how?

Like this one:


const headers = {
  'checkout-account': '1234',
  'checkout-algorithm': 'sha256',
  'checkout-method': 'POST',
  'checkout-nonce': '564635208570151',
  'checkout-timestamp': '2018-07-06T10:01:31.904Z',
};

const calculateHmac = (body=false, params) => {
  const hmacPayload = Object.keys(params)
    .sort()
    .map((key) => [key, params[key]].join(':'))
    .concat(body ? JSON.stringify(body) : '')
    .join('\n');
};

calculateHmac(false, headers);
chifmaster113
  • 13
  • 1
  • 1

1 Answers1

0

More or less the same code in Rust:

use itertools::Itertools;
use std::collections::HashMap;

fn main() {
    let headers = HashMap::from([
        ("checkout-account", "1234"),
        ("checkout-algorithm", "sha256"),
        ("checkout-method", "POST"),
        ("checkout-nonce", "564635208570151"),
        ("checkout-timestamp", "2018-07-06T10,01,31.904Z"),
    ]);

    let hmac_payload = headers
        .keys()
        .sorted()
        .map(|key| format!("{}:{}", key, headers[key]))
        .join("\n");

    println!("{hmac_payload}");
}

Plaground link

As @cdhowie pointed out, Rust gives you the option to sort items by key instead of sorting keys only and then performing a lookup each time:

    let hmac_payload = headers
        .iter()
        .sorted_by_key(|item| item.0)
        .map(|item| format!("{}:{}", item.0, item.1))
        .join("\n");

As @Caesar pointed out, using BTreeMap instead of HashMap would be a more efficient solution since it stores items sorted by their keys, thus you won't need to sort items at all.

aedm
  • 5,596
  • 2
  • 32
  • 36
  • 2
    Why not use a `BTreeMap` instead of a `HashMap`? It'll save on the trouble of sorting after and using itertools. – Caesar Mar 11 '22 at 15:48
  • That's totally right. I'll leave it as is since I think the question is mostly about sorting (maybe just my assumption), but yes, using BTreeMap would probably make it a more efficient solution. – aedm Mar 11 '22 at 15:56
  • I added your remark to the answer. – aedm Mar 11 '22 at 16:01
  • 2
    Instead of `.keys().sorted()` then looking up the keys, would it not be better to use `.iter().sorted_by_key(|i| i.0)`? This would avoid having to look up each key's value as the values would be part of the iteration. Same with BTreeMap (iterate the keys+values not just the keys). – cdhowie Mar 11 '22 at 16:05
  • @cdhowie Thanks, I added your remarks, too. – aedm Mar 11 '22 at 16:13