///|
fn read_endpoint(
element : XmlElementValue,
budget : ParseBudget,
) -> Endpoint raise GraphError {
graphml_element(element, "endpoint")
check_bound("endpoints", budget.endpoints + 1, budget.limits.endpoints)
budget.endpoints = budget.endpoints + 1
let children = element_children(element)
for child in children {
graphml_element(child, "desc")
}
{
id: attribute_value(element, "id"),
node: required_attribute(element, "node"),
port: attribute_value(element, "port"),
kind: EndpointKind::from_name(
attribute_value(element, "type").unwrap_or("undir"),
),
description: read_description(children, "endpoint"),
extra: extra_attributes(element, ["id", "node", "port", "type"]),
namespaces: element.namespaces,
}
}
///|
fn read_hyperedge(
element : XmlElementValue,
keys : Map[String, Key],
budget : ParseBudget,
) -> Hyperedge raise GraphError {
graphml_element(element, "hyperedge")
check_bound("edges_and_hyperedges", budget.edges + 1, budget.limits.edges)
budget.edges = budget.edges + 1
let children = element_children(element)
let hyperedge : Hyperedge = {
id: attribute_value(element, "id"),
description: read_description(children, "hyperedge"),
data: [],
endpoints: [],
graph: None,
extra: extra_attributes(element, ["id"]),
namespaces: element.namespaces,
}
let mut nested_graph : Graph? = None
for child in children {
require(
child.namespace_uri == Some(GRAPHML_URI),
"hyperedge",
"unknown child namespace",
)
require(
nested_graph is None,
"hyperedge.graph",
"nested graph must be last",
)
match child.name {
"desc" => ()
"data" => hyperedge.data.push(read_datum(child, keys))
"endpoint" => hyperedge.endpoints.push(read_endpoint(child, budget))
"graph" => nested_graph = Some(read_graph(child, keys, budget))
_ => raise Unsupported(path="hyperedge", feature=child.name)
}
}
{ ..hyperedge, graph: nested_graph, }
}