use crate::StructuralModelError;
use serde::{Deserialize, Deserializer, Serialize};
use std::ops::Deref;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
#[serde(transparent)]
pub struct OperandList<T, const MIN: usize> {
items: Vec<T>,
}
impl<T, const MIN: usize> OperandList<T, MIN> {
pub fn try_new(items: Vec<T>) -> Result<Self, StructuralModelError> {
if items.len() < MIN {
return Err(StructuralModelError::InvalidFormat {
kind: "structural operands",
value: items.len().to_string(),
message: match MIN {
1 => "requires at least one operand",
2 => "requires at least two operands",
_ => "too few operands for the structural minimum",
},
});
}
Ok(Self { items })
}
#[must_use]
pub fn as_slice(&self) -> &[T] {
&self.items
}
#[must_use]
pub fn into_vec(self) -> Vec<T> {
self.items
}
}
impl<T> OperandList<T, 0> {
#[must_use]
pub fn new(items: Vec<T>) -> Self {
Self { items }
}
}
impl<T, const MIN: usize> Deref for OperandList<T, MIN> {
type Target = [T];
fn deref(&self) -> &Self::Target {
self.as_slice()
}
}
impl<'a, T, const MIN: usize> IntoIterator for &'a OperandList<T, MIN> {
type Item = &'a T;
type IntoIter = std::slice::Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.items.iter()
}
}
impl<'de, T: Deserialize<'de>, const MIN: usize> Deserialize<'de> for OperandList<T, MIN> {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Self::try_new(Vec::<T>::deserialize(deserializer)?).map_err(serde::de::Error::custom)
}
}