1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
use crate::MultiMap;
use serde::de::DeserializeOwned;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::cmp::Ord;
use std::collections::{BTreeMap, HashMap};
use std::convert::TryFrom;
use std::error::Error;

/// Stringifies an object to nicely formatted JSON.
pub fn to_json<T: Serialize>(obj: &T) -> String {
    serde_json::to_string_pretty(obj).unwrap()
}

/// Stringifies an object to terse JSON.
pub fn to_json_terse<T: Serialize>(obj: &T) -> String {
    serde_json::to_string(obj).unwrap()
}

/// Deserializes an object from a JSON string.
pub fn from_json<T: DeserializeOwned>(raw: &Vec<u8>) -> Result<T, Box<dyn Error>> {
    serde_json::from_slice(raw).map_err(|x| x.into())
}

/// Deserializes an object from JSON, from a reader.
pub fn from_json_reader<R: std::io::Read, T: DeserializeOwned>(reader: R) -> Result<T, String> {
    serde_json::from_reader(reader).map_err(|x| x.to_string())
}

/// Deserializes an object from the bincode format.
pub fn from_binary<T: DeserializeOwned>(raw: &Vec<u8>) -> Result<T, Box<dyn Error>> {
    bincode::deserialize(raw).map_err(|x| x.into())
}

/// Deserializes an object from the bincode format, from a reader.
pub fn from_binary_reader<R: std::io::Read, T: DeserializeOwned>(reader: R) -> Result<T, String> {
    bincode::deserialize_from(reader).map_err(|x| x.to_string())
}

/// The number of bytes for an object serialized to bincode.
pub fn serialized_size_bytes<T: Serialize>(obj: &T) -> usize {
    bincode::serialized_size(obj).unwrap() as usize
}

/// Serializes a BTreeMap as a list of tuples. Necessary when the keys are structs; see
/// https://github.com/serde-rs/json/issues/402.
pub fn serialize_btreemap<S: Serializer, K: Serialize, V: Serialize>(
    map: &BTreeMap<K, V>,
    s: S,
) -> Result<S::Ok, S::Error> {
    map.iter().collect::<Vec<(_, _)>>().serialize(s)
}

/// Deserializes a BTreeMap from a list of tuples. Necessary when the keys are structs; see
/// https://github.com/serde-rs/json/issues/402.
pub fn deserialize_btreemap<
    'de,
    D: Deserializer<'de>,
    K: Deserialize<'de> + Ord,
    V: Deserialize<'de>,
>(
    d: D,
) -> Result<BTreeMap<K, V>, D::Error> {
    let vec = <Vec<(K, V)>>::deserialize(d)?;
    let mut map = BTreeMap::new();
    for (k, v) in vec {
        map.insert(k, v);
    }
    Ok(map)
}

/// Serializes a HashMap as a list of tuples, first sorting by the keys. This ensures the
/// serialized form is deterministic.
pub fn serialize_hashmap<S: Serializer, K: Serialize + Ord, V: Serialize>(
    map: &HashMap<K, V>,
    s: S,
) -> Result<S::Ok, S::Error> {
    let mut list: Vec<(&K, &V)> = map.iter().collect();
    list.sort_by_key(|(k, _)| k.clone());
    list.serialize(s)
}

/// Deserializes a HashMap from a list of tuples.
pub fn deserialize_hashmap<
    'de,
    D: Deserializer<'de>,
    K: Deserialize<'de> + std::hash::Hash + Eq,
    V: Deserialize<'de>,
>(
    d: D,
) -> Result<HashMap<K, V>, D::Error> {
    let vec = <Vec<(K, V)>>::deserialize(d)?;
    let mut map = HashMap::new();
    for (k, v) in vec {
        map.insert(k, v);
    }
    Ok(map)
}

/// Serializes a MultiMap.
pub fn serialize_multimap<
    S: Serializer,
    K: Serialize + Eq + Ord + Clone,
    V: Serialize + Eq + Ord + Clone,
>(
    map: &MultiMap<K, V>,
    s: S,
) -> Result<S::Ok, S::Error> {
    // TODO maybe need to sort to have deterministic output
    map.raw_map().iter().collect::<Vec<(_, _)>>().serialize(s)
}

/// Deserializes a MultiMap.
pub fn deserialize_multimap<
    'de,
    D: Deserializer<'de>,
    K: Deserialize<'de> + Eq + Ord + Clone,
    V: Deserialize<'de> + Eq + Ord + Clone,
>(
    d: D,
) -> Result<MultiMap<K, V>, D::Error> {
    let vec = <Vec<(K, Vec<V>)>>::deserialize(d)?;
    let mut map = MultiMap::new();
    for (key, values) in vec {
        for value in values {
            map.insert(key.clone(), value);
        }
    }
    Ok(map)
}

/// Serializes a `usize` as a `u32` to save space. Useful when you need `usize` for indexing, but
/// the values don't exceed 2^32.
pub fn serialize_usize<S: Serializer>(x: &usize, s: S) -> Result<S::Ok, S::Error> {
    if let Ok(x) = u32::try_from(*x) {
        x.serialize(s)
    } else {
        Err(serde::ser::Error::custom(format!("{} can't fit in u32", x)))
    }
}

/// Deserializes a `usize` from a `u32`.
pub fn deserialize_usize<'de, D: Deserializer<'de>>(d: D) -> Result<usize, D::Error> {
    let x = <u32>::deserialize(d)?;
    Ok(x as usize)
}