use core::num::NonZeroU32;
use alloc::vec::Vec;
use crate::errors::{Result, RucrfError};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Edge {
target: usize,
pub(crate) label: NonZeroU32,
}
impl Edge {
#[inline(always)]
#[must_use]
pub const fn new(target: usize, label: NonZeroU32) -> Self {
Self { target, label }
}
#[inline(always)]
#[must_use]
pub const fn target(&self) -> usize {
self.target
}
#[inline(always)]
#[must_use]
pub const fn label(&self) -> NonZeroU32 {
self.label
}
}
#[derive(Clone, Default, Debug)]
pub struct Node {
edges: Vec<Edge>,
}
impl Node {
#[inline(always)]
pub fn edges(&self) -> &[Edge] {
&self.edges
}
}
pub struct Lattice {
nodes: Vec<Node>,
}
impl Lattice {
#[inline(always)]
pub fn new(length: usize) -> Result<Self> {
if length == 0 {
return Err(RucrfError::invalid_argument("length must be >= 1"));
}
let nodes = vec![Node::default(); length + 1];
Ok(Self { nodes })
}
#[inline(always)]
pub fn add_edge(&mut self, pos: usize, edge: Edge) -> Result<()> {
if edge.target() <= pos {
return Err(RucrfError::invalid_argument("edge.target() must be > pos"));
}
if edge.target() > self.nodes.len() {
return Err(RucrfError::invalid_argument(
"edge.target() must be <= length",
));
}
self.nodes[pos].edges.push(edge);
Ok(())
}
#[inline(always)]
#[must_use]
pub fn nodes(&self) -> &[Node] {
&self.nodes
}
}