use crate::error::{HullabalooError, HullabalooResult};
use crate::matrix::Matrix;
use calculo::num::Num;
pub trait Geometrizable: Clone {
type N: Num;
fn into_vertices(self) -> Vec<Vec<Self::N>>;
fn into_matrix(self) -> HullabalooResult<Matrix<Self::N>>
where
Self: Sized,
{
let vertices = self.into_vertices();
let Some(first) = vertices.first() else {
return Err(HullabalooError::InvalidInput {
message: "howzat conversion requires at least one vertex".to_string(),
});
};
let dim = first.len();
if dim == 0 {
return Err(HullabalooError::InvalidInput {
message: "howzat conversion requires positive vertex dimension".to_string(),
});
}
if vertices.iter().skip(1).any(|v| v.len() != dim) {
return Err(HullabalooError::InvalidInput {
message: "howzat conversion requires consistent vertex dimensions".to_string(),
});
}
let generator_rows: Vec<Vec<Self::N>> = vertices
.into_iter()
.map(|coords| {
let mut row = Vec::with_capacity(coords.len() + 1);
row.push(Self::N::one());
row.extend(coords);
row
})
.collect();
Matrix::from_rows(generator_rows).map_err(Into::into)
}
}
impl<N: Num> Geometrizable for Vec<Vec<N>> {
type N = N;
fn into_vertices(self) -> Vec<Vec<Self::N>> {
self
}
}