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
use smartnoise_validator::errors::*;
use smartnoise_validator::proto;
use smartnoise_validator::base::{ReleaseNode, Value};
use std::collections::{HashMap};
use smartnoise_validator::utilities::serial::{parse_release_node};
pub fn evaluate_function(
function: &proto::Function,
arguments: HashMap<String, Value>,
) -> Result<HashMap<String, Value>> {
let proto::Function {
computation_graph, release, arguments: arguments_names, outputs
} = function;
let release = release.clone()
.unwrap_or_else(|| proto::Release { values: HashMap::new() }).values;
let computation_graph = computation_graph.clone()
.ok_or_else(|| Error::from("computation_graph must be defined"))?;
let mut release = release.into_iter()
.map(|(idx, release_node)| Ok((idx, parse_release_node(release_node))))
.collect::<Result<HashMap<u32, ReleaseNode>>>()?;
arguments_names.iter()
.try_for_each(|(name, id)| {
let argument = arguments.get(name)
.ok_or_else(|| Error::from(format!("missing argument in function evaluation: {}", name)))?;
release.insert(*id, ReleaseNode {
value: argument.clone(),
privacy_usages: None,
public: true,
});
Ok::<_, Error>(())
})?;
let (release, warnings) = crate::release(
None,
computation_graph.value,
release,
proto::FilterLevel::All)?;
outputs.iter()
.map(|(name, id)| Ok((
name.clone(),
release.get(id)
.ok_or_else(|| Error::from(format!("Function failed to evaluate. Warnings: {:?}", warnings)))?
.value.clone()
)))
.collect::<Result<HashMap<String, Value>>>()
}