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
use crate::errors::*;
use crate::{proto, base};
use crate::components::{Expandable};
use crate::base::{ValueProperties, IndexKey, Value, ReleaseNode};
use crate::utilities::{get_literal};
use crate::utilities::inference::infer_property;
use indexmap::set::IndexSet;
use indexmap::map::IndexMap;
impl Expandable for proto::Map {
fn expand_component(
&self,
_privacy_definition: &Option<proto::PrivacyDefinition>,
component: &proto::Component,
public_arguments: &IndexMap<IndexKey, &Value>,
properties: &base::NodeProperties,
component_id: u32,
mut maximum_id: u32
) -> Result<base::ComponentExpansion> {
let mut expansion = base::ComponentExpansion::default();
let mapped_component = self.component.as_ref()
.ok_or_else(|| "component must be defined")?;
let (props_partitioned, props_singular): (
IndexMap<IndexKey, ValueProperties>,
IndexMap<IndexKey, ValueProperties>
) = properties.clone().into_iter()
.partition(|(_, props)| props.partitions().is_ok());
let indexes = props_partitioned.values()
.map(|v| Ok(v.partitions()?.children.keys().collect()))
.collect::<Result<Vec<Vec<&IndexKey>>>>()?.into_iter().flatten()
.collect::<IndexSet<&IndexKey>>();
let arguments = component.arguments();
let union_arguments = indexes.into_iter()
.map(|partition_idx| Ok((
partition_idx.clone(),
props_partitioned.iter()
.map(|(name, _)| {
maximum_id += 1;
let id_index_name = maximum_id;
let (patch_node, release) = get_literal(Value::from_index_key(partition_idx.clone())?, component.submission)?;
expansion.computation_graph.insert(id_index_name, patch_node);
expansion.properties.insert(id_index_name, infer_property(&release.value, None, id_index_name)?);
expansion.releases.insert(id_index_name, release);
maximum_id += 1;
let id_index = maximum_id;
let id_data = *arguments.get(name)
.ok_or_else(|| Error::from(format!("{:?}: missing from component arguments", name)))?;
expansion.computation_graph.insert(id_index, proto::Component {
arguments: Some(proto::ArgumentNodeIds::new(indexmap!["data".into() => id_data, "names".into() => id_index_name])),
omit: true,
submission: component.submission,
variant: Some(proto::component::Variant::Index(proto::Index {})),
});
match (public_arguments.get(name), properties.get(name)) {
(Some(release_node), Some(properties)) => match (
release_node.ref_partitions()?.get(partition_idx),
properties.partitions()?.children.get(partition_idx)
) {
(Some(partition_value), Some(partition_properties)) => {
expansion.releases.insert(id_index, ReleaseNode {
value: partition_value.clone(),
privacy_usages: None,
public: partition_properties.is_public()
});
expansion.properties.insert(id_index, partition_properties.clone());
},
_ => expansion.traversal.push(id_index)
},
_ => expansion.traversal.push(id_index)
}
Ok((name.clone(), id_index))
})
.chain(props_singular.clone().into_iter().map(|(name, _)| {
let id_arg = arguments.get(&name).ok_or_else(||
format!("{:?}: missing from component arguments", name))?;
Ok((name, *id_arg))
}))
.collect::<Result<IndexMap<IndexKey, u32>>>()?
)))
.collect::<Result<IndexMap<IndexKey, IndexMap<IndexKey, u32>>>>()?.into_iter()
.map(|(partition_idx, arguments)| {
maximum_id += 1;
let id_inner_component = maximum_id;
let mut inner_component = *mapped_component.clone();
inner_component.arguments = Some(proto::ArgumentNodeIds::new(arguments));
inner_component.omit = true;
expansion.computation_graph.insert(id_inner_component, inner_component);
expansion.traversal.push(id_inner_component);
Ok((partition_idx, id_inner_component))
})
.collect::<Result<IndexMap<IndexKey, u32>>>()?;
expansion.computation_graph.insert(component_id, proto::Component {
arguments: Some(proto::ArgumentNodeIds::new(union_arguments)),
omit: component.omit,
submission: component.submission,
variant: Some(proto::component::Variant::Union(proto::Union {
flatten: false
}))
});
expansion.traversal.push(component_id);
Ok(expansion)
}
}