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
use crate::errors::*;
use serde::{Deserialize, Serialize};
use crate::proto;
use crate::base;
use serde_json::Value;
use ndarray::prelude::*;
#[derive(Serialize, Deserialize)]
pub struct JSONRelease {
pub description: String,
pub variables: Value,
pub statistic: String,
#[serde(rename(serialize = "releaseInfo", deserialize = "releaseInfo"))]
pub release_info: Value,
#[serde(rename(serialize = "privacyLoss", deserialize = "privacyLoss"))]
pub privacy_loss: Value,
pub accuracy: Option<Accuracy>,
pub submission: u32,
#[serde(rename(serialize = "nodeID", deserialize = "nodeID"))]
pub node_id: u32,
pub postprocess: bool,
#[serde(rename(serialize = "algorithmInfo", deserialize = "algorithmInfo"))]
pub algorithm_info: AlgorithmInfo,
}
#[derive(Serialize, Deserialize)]
pub struct Accuracy {
#[serde(rename(serialize = "accuracyValue", deserialize = "accuracyValue"))]
pub accuracy_value: f64,
pub alpha: f64,
}
#[derive(Serialize, Deserialize)]
pub struct AlgorithmInfo {
pub mechanism: String,
pub name: String,
pub cite: String,
pub argument: Value,
}
pub fn value_to_json(value: &base::Value) -> Result<serde_json::Value> {
match value {
base::Value::Array(array) => match array {
base::Array::Float(value) => arraynd_to_json(value),
base::Array::Int(value) => arraynd_to_json(value),
base::Array::Str(value) => arraynd_to_json(value),
base::Array::Bool(value) => arraynd_to_json(value)
},
_ => Err("only arrayND to json is implemented".into())
}
}
pub fn arraynd_to_json<T: Serialize + Clone>(array: &ArrayD<T>) -> Result<serde_json::Value> {
match array.ndim() {
0 => Ok(serde_json::json!(array.first().unwrap())),
1 => Ok(serde_json::json!(array.clone().into_dimensionality::<Ix1>()?.to_vec())),
2 => Ok(serde_json::json!(array.genrows().into_iter().map(|row| row.iter().cloned().collect::<Vec<T>>()).collect::<Vec<Vec<T>>>())),
_ => Err("array must have dimensionality less than 2".into())
}
}
pub fn privacy_usage_to_json(privacy_usage: &proto::PrivacyUsage) -> serde_json::Value {
match privacy_usage.distance.clone().unwrap() {
proto::privacy_usage::Distance::Approximate(distance) =>
serde_json::json!({"name": "approximate", "epsilon": distance.epsilon, "delta": distance.delta})
}
}