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
146
147
148
149
150
151
use std::cmp::Ord;
use std::collections::{BTreeMap, HashMap};
use std::convert::TryFrom;

use anyhow::Result;
use serde::de::DeserializeOwned;
use serde::{Deserialize, Deserializer, Serialize, Serializer};

use crate::MultiMap;

/// 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: &[u8]) -> Result<T> {
    serde_json::from_slice(raw).map_err(|err| err.into())
}

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

/// Deserializes an object from the bincode format.
pub fn from_binary<T: DeserializeOwned>(raw: &[u8]) -> Result<T> {
    bincode::deserialize(raw).map_err(|err| err.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> {
    bincode::deserialize_from(reader).map_err(|err| err.into())
}

/// 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
}

/// Transforms an object to bincoded bytes.
pub fn to_binary<T: Serialize>(obj: &T) -> Vec<u8> {
    bincode::serialize(obj).unwrap()
}

/// 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);
    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> {
    map.borrow().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)
}