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
#[cfg(feature = "with-serde")]
use serde::{Deserialize, Serialize};

/// Serialize a node (including all child nodes) into JSON.
///
/// Example with merkle tree:
/// ```
/// use tallytree::serialize::to_json;
/// use tallytree::generate::generate_tree;
/// let tree = generate_tree(vec![
///     ([0xaa; 32], vec![1, 0]),
///     ([0xbb; 32], vec![0, 1]),
/// ], false).unwrap();
/// let tree_json: String = to_json(&tree).unwrap();
/// ```
///
/// Example with proofs:
/// ```
/// use tallytree::serialize::{to_json, from_json};
/// use tallytree::proof::*;
/// use tallytree::generate::generate_tree;
/// use tallytree::Validation;
/// let tree = generate_tree(vec![
///     ([0xaa; 32], vec![1, 0]),
///     ([0xbb; 32], vec![1, 0]),
///     ([0xcc; 32], vec![0, 1]),
/// ], false).unwrap();
/// let proof_count = create_proof_of_vote_count(&tree, &Validation::Strict).unwrap();
/// let proof_node = create_inclusion_exclusion_proof(&tree, &[0xaa; 32], &Validation::Strict).unwrap();
///
/// assert_eq!(proof_count, from_json(&to_json(&proof_count).unwrap()).unwrap());
/// assert_eq!(proof_node, from_json(&to_json(&proof_node).unwrap()).unwrap());
/// ```
#[cfg(feature = "with-serde")]
pub fn to_json<T: Serialize>(data: &T) -> Result<String, String> {
    match serde_json::to_string(&data) {
        Result::Ok(v) => Ok(v),
        Result::Err(e) => Err(e.to_string()),
    }
}

/// Deserialize a node (including all child nodes) from JSON.
///
/// Example with merkle tree:
/// ```
/// use tallytree::serialize::{to_json, from_json};
/// use tallytree::generate::generate_tree;
/// use tallytree::node::NodeRef;
/// let tree = generate_tree(vec![
///     ([0xaa; 32], vec![1, 0]),
///     ([0xbb; 32], vec![0, 1]),
/// ], false).unwrap();
/// let tree_json: String = to_json(&tree).unwrap();
/// let tree_deserialized: NodeRef = from_json(&tree_json).unwrap();
/// assert_eq!(tree, tree_deserialized);
/// ```
///
/// Example with proofs:
/// ```
/// use tallytree::serialize::{to_json, from_json};
/// use tallytree::proof::*;
/// use tallytree::generate::generate_tree;
/// use tallytree::Validation;
/// let tree = generate_tree(vec![
///     ([0xaa; 32], vec![1, 0]),
///     ([0xbb; 32], vec![1, 0]),
///     ([0xcc; 32], vec![0, 1]),
/// ], true).unwrap();
/// let proof_count = create_proof_of_vote_count(&tree, &Validation::Strict).unwrap();
/// let proof_node = create_inclusion_exclusion_proof(&tree, &[0xaa; 32], &Validation::Strict).unwrap();
///
/// assert_eq!(proof_count, from_json(&to_json(&proof_count).unwrap()).unwrap());
/// assert_eq!(proof_node, from_json(&to_json(&proof_node).unwrap()).unwrap());
/// ```
#[cfg(feature = "with-serde")]
pub fn from_json<'a, T: Deserialize<'a>>(json: &'a str) -> Result<T, String> {
    match serde_json::from_str(json) {
        Result::Ok(v) => Ok(v),
        Result::Err(e) => Err(e.to_string()),
    }
}

#[cfg(test)]
#[cfg(feature = "with-serde")]
mod tests {
    use super::*;
    use crate::proof::*;
    use crate::Validation;

    #[test]
    fn test_serialize_node_json() {
        let tree = crate::generate::generate_tree(
            vec![
                ([0xaa; 32], vec![1, 0]),
                ([0xbb; 32], vec![1, 0]),
                ([0xcc; 32], vec![0, 1]),
            ],
            false,
        )
        .unwrap();
        let json = to_json(&tree).unwrap();
        let tree_deserialized = from_json(&json).unwrap();
        assert_eq!(tree, tree_deserialized);
    }

    #[test]
    fn test_serialize_count_proof() {
        let tree = crate::generate::generate_tree(
            vec![
                ([0xaa; 32], vec![1, 0]),
                ([0xbb; 32], vec![1, 0]),
                ([0xcc; 32], vec![0, 1]),
            ],
            true,
        )
        .unwrap();
        let proof = create_proof_of_vote_count(&tree, &Validation::Strict).unwrap();
        let proof_json = to_json(&proof).unwrap();
        let proof_deserialized: Proof = from_json(&proof_json).unwrap();
        assert_eq!(proof, proof_deserialized);
    }

    #[test]
    fn serialize_inclusion_exclusion_proof() {
        let tree = crate::generate::generate_tree(
            vec![
                ([0xaa; 32], vec![1, 0]),
                ([0xbb; 32], vec![1, 0]),
                ([0xcc; 32], vec![0, 1]),
            ],
            true,
        )
        .unwrap();
        let proof =
            create_inclusion_exclusion_proof(&tree, &[0xaa; 32], &Validation::Strict).unwrap();
        let proof_json = to_json(&proof).unwrap();
        let proof_deserialized: (InclusionProof, ExclusionProof) = from_json(&proof_json).unwrap();
        assert_eq!(proof, proof_deserialized);
    }
}