///|
/// A transition identified by state IDs instead of numeric indices.
pub(all) struct NamedEdge {
from : String
to : String
action : String
} derive(Debug)
///|
pub extend NamedEdge with Debug::{to_repr}
///|
pub(all) enum NamedModelError {
DuplicateName(String)
UnknownState(String)
InvalidModel(ModelError)
} derive(Debug)
///|
pub extend NamedModelError with Debug::{to_repr}
///|
/// Build a finite graph using stable state IDs. Every named transition must
/// refer to a declared state. A terminal state receives a stutter self-loop.
pub fn Model::from_named(
states : Array[State],
edges : Array[NamedEdge],
initial : String,
) -> Result[Model, NamedModelError] {
if states.is_empty() {
return Err(InvalidModel(EmptyStates))
}
let indices : Map[String, Int] = Map([])
for i in 0.. index
None => return Err(UnknownState(initial))
}
let indexed : Array[Edge] = []
for edge in edges {
let from = match indices.get(edge.from) {
Some(index) => index
None => return Err(UnknownState(edge.from))
}
let to = match indices.get(edge.to) {
Some(index) => index
None => return Err(UnknownState(edge.to))
}
indexed.push({ from, to, action: edge.action, })
}
match Model::new(states, indexed, initial=initial_index) {
Ok(model) => Ok(model)
Err(error) => Err(InvalidModel(error))
}
}