use rspace_traits::RawSpace;
pub trait TriadRepr
where
Self: RawSpace,
{
private! {}
fn from_arr(arr: [Self::Elem; 3]) -> Self
where
Self: Sized;
fn from_iter<I>(iter: impl IntoIterator<Item = Self::Elem, IntoIter = I>) -> Option<Self>
where
I: ExactSizeIterator<Item = Self::Elem>,
Self: Sized,
{
let mut it = iter.into_iter();
if it.len() != 3 {
#[cfg(feature = "tracing")]
tracing::error! { "expected an iterator of length 3, found {}", it.len() }
return None;
}
let a = it.next()?;
let b = it.next()?;
let c = it.next()?;
Some(Self::from_arr([a, b, c]))
}
fn len(&self) -> usize {
3
}
fn root(&self) -> &Self::Elem;
fn third(&self) -> &Self::Elem;
fn fifth(&self) -> &Self::Elem;
}
pub trait TriadReprMut: TriadRepr
where
Self::Elem: Sized,
{
fn root_mut(&mut self) -> &mut Self::Elem;
fn third_mut(&mut self) -> &mut Self::Elem;
fn fifth_mut(&mut self) -> &mut Self::Elem;
fn set_root(&mut self, root: Self::Elem) -> &mut Self {
*self.root_mut() = root;
self
}
fn set_third(&mut self, third: Self::Elem) -> &mut Self {
*self.third_mut() = third;
self
}
fn set_fifth(&mut self, fifth: Self::Elem) -> &mut Self {
*self.fifth_mut() = fifth;
self
}
}
impl<T> TriadRepr for (T, T, T) {
seal! {}
fn from_arr([a, b, c]: [Self::Elem; 3]) -> Self
where
Self: Sized,
{
(a, b, c)
}
fn root(&self) -> &T {
&self.0
}
fn third(&self) -> &T {
&self.1
}
fn fifth(&self) -> &T {
&self.2
}
}
impl<T> TriadReprMut for (T, T, T) {
fn root_mut(&mut self) -> &mut T {
&mut self.0
}
fn third_mut(&mut self) -> &mut T {
&mut self.1
}
fn fifth_mut(&mut self) -> &mut T {
&mut self.2
}
}
impl<T> TriadRepr for [T; 3] {
seal! {}
fn from_arr(arr: [Self::Elem; 3]) -> Self
where
Self: Sized,
{
arr
}
fn root(&self) -> &T {
&self[0]
}
fn third(&self) -> &T {
&self[1]
}
fn fifth(&self) -> &T {
&self[2]
}
}
impl<T> TriadReprMut for [T; 3] {
fn root_mut(&mut self) -> &mut T {
&mut self[0]
}
fn third_mut(&mut self) -> &mut T {
&mut self[1]
}
fn fifth_mut(&mut self) -> &mut T {
&mut self[2]
}
}