///|
fn read_port(
element : XmlElementValue,
keys : Map[String, Key],
budget : ParseBudget,
) -> Port raise GraphError {
graphml_element(element, "port")
check_bound("ports", budget.ports + 1, budget.limits.ports)
budget.ports = budget.ports + 1
let children = element_children(element)
let port : Port = {
name: required_attribute(element, "name"),
description: read_description(children, "port"),
data: [],
ports: [],
extra: extra_attributes(element, ["name"]),
namespaces: element.namespaces,
}
for child in children {
require(
child.namespace_uri == Some(GRAPHML_URI),
"port",
"unknown child namespace",
)
match child.name {
"desc" => ()
"data" => port.data.push(read_datum(child, keys))
"port" => port.ports.push(read_port(child, keys, budget))
_ => raise Unsupported(path="port", feature=child.name)
}
}
port
}
///|
fn collect_ports(
ports : Array[Port],
names : Map[String, Bool],
catalog : Map[String, Key],
) -> Unit raise GraphError {
for port in ports {
valid_token(port.name, "port.name")
require(
!names.contains(port.name),
"port.name",
"duplicate port \{port.name}",
)
names[port.name] = true
check_data(port.data, PortScope, catalog)
collect_ports(port.ports, names, catalog)
}
}
///|
fn check_port_reference(
port : String?,
node : String,
node_ports : Map[String, Map[String, Bool]],
) -> Unit raise GraphError {
if port is Some(name) {
valid_token(name, "port.reference")
let names = node_ports.get(node).unwrap_or(Map([]))
require(
names.contains(name),
"port.reference",
"missing port \{node}:\{name}",
)
}
}