#![forbid(unsafe_code)]
#![doc = include_str!("../README.md")]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct IncidencePair {
point: usize,
line: usize,
}
impl IncidencePair {
#[must_use]
pub const fn new(point: usize, line: usize) -> Self {
Self { point, line }
}
#[must_use]
pub const fn point(self) -> usize {
self.point
}
#[must_use]
pub const fn line(self) -> usize {
self.line
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct IncidenceMatrix {
point_count: usize,
line_count: usize,
entries: Vec<bool>,
}
impl IncidenceMatrix {
#[must_use]
pub fn new(point_count: usize, line_count: usize, entries: Vec<bool>) -> Option<Self> {
if point_count > 0 && line_count > 0 && entries.len() == point_count * line_count {
Some(Self {
point_count,
line_count,
entries,
})
} else {
None
}
}
#[must_use]
pub const fn point_count(&self) -> usize {
self.point_count
}
#[must_use]
pub const fn line_count(&self) -> usize {
self.line_count
}
#[must_use]
pub fn is_incident(&self, point: usize, line: usize) -> Option<bool> {
if point < self.point_count && line < self.line_count {
Some(self.entries[(point * self.line_count) + line])
} else {
None
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct IncidenceStructure {
point_count: usize,
line_count: usize,
pairs: Vec<IncidencePair>,
}
impl IncidenceStructure {
#[must_use]
pub fn new(point_count: usize, line_count: usize, pairs: Vec<IncidencePair>) -> Option<Self> {
if point_count > 0
&& line_count > 0
&& pairs
.iter()
.all(|pair| pair.point() < point_count && pair.line() < line_count)
{
Some(Self {
point_count,
line_count,
pairs,
})
} else {
None
}
}
#[must_use]
pub const fn point_count(&self) -> usize {
self.point_count
}
#[must_use]
pub const fn line_count(&self) -> usize {
self.line_count
}
#[must_use]
pub fn pairs(&self) -> &[IncidencePair] {
&self.pairs
}
#[must_use]
pub fn incidence_count(&self) -> usize {
self.pairs.len()
}
}
#[cfg(test)]
mod tests {
use super::{IncidenceMatrix, IncidencePair, IncidenceStructure};
#[test]
fn validates_incidence_structures() {
let pair = IncidencePair::new(1, 0);
let structure = IncidenceStructure::new(2, 1, vec![pair]).expect("valid structure");
let matrix = IncidenceMatrix::new(2, 1, vec![false, true]).expect("valid matrix");
assert_eq!(structure.point_count(), 2);
assert_eq!(structure.line_count(), 1);
assert_eq!(structure.incidence_count(), 1);
assert_eq!(matrix.is_incident(1, 0), Some(true));
assert_eq!(IncidenceStructure::new(1, 1, vec![pair]), None);
}
}