pub fn flatten<'a, I>(nodes: I) -> IndexMap<String, FlatNode>where
I: IntoIterator<Item = &'a IfcxNode>,Expand description
Merges input nodes into one FlatNode per path.
This borrows the nodes, so every attribute value is copied into the
result. When the nodes are not needed afterwards, flatten_owned gives
the same result without copying them, which is several times faster on
large models.
nodes must be in layer order, weakest first: the nodes of one file in
file order, and for a layer stack the nodes of each layer after those of
the layers it overrides. Later nodes win, as described on
FlatNode::merge.
The result is keyed by path, in order of each path’s first appearance.
Every map keeps insertion order. Upstream stores these maps in JavaScript
objects, which list integer-like keys such as "2" first; that ordering
quirk is not reproduced, the content is the same.
Paths are compared as plain strings, so a/b is a node of its own here;
composition applies it to child b of a.
use openbim_ifcx::{flatten, IfcxNode};
let layers: Vec<IfcxNode> = serde_json::from_str(r#"[
{"path": "w", "children": {"Body": "b1"}, "inherits": {"Type": "t"},
"attributes": {"x::height": 2.5}},
{"path": "w", "children": {"Body": null}, "inherits": {"Type": null},
"attributes": {"x::height": 3.0}}
]"#)?;
let flat = flatten(&layers);
let wall = &flat["w"];
assert_eq!(wall.children["Body"], None);
assert!(wall.inherits.is_empty());
assert_eq!(*wall.attributes["x::height"], 3.0);