use super::element::Element;
#[derive(Debug, Clone, PartialEq)]
pub struct PerChannel<T> {
pub all: Element<T>,
pub by_channel: [Element<T>; 2],
}
impl<T> PerChannel<T> {
pub fn new(value: T) -> Self {
Self {
all: Element::Set(value),
by_channel: [Element::Inherit, Element::Inherit],
}
}
pub fn resolve(&self, ch: u8) -> Option<&T> {
let i = ch as usize;
debug_assert!(i < 2, "channel index out of range: {ch}");
let parent = self.all.as_set();
self.by_channel.get(i).and_then(|e| e.cascade(parent))
}
}
impl<T: Default> Default for PerChannel<T> {
fn default() -> Self {
Self {
all: Element::Set(T::default()),
by_channel: [Element::Inherit, Element::Inherit],
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Sided<T> {
pub all: Element<T>,
pub by_channel: [Element<T>; 2],
pub by_channel_side: [[Element<T>; 2]; 2],
}
impl<T> Sided<T> {
pub fn new(value: T) -> Self {
Self {
all: Element::Set(value),
by_channel: [Element::Inherit, Element::Inherit],
by_channel_side: [
[Element::Inherit, Element::Inherit],
[Element::Inherit, Element::Inherit],
],
}
}
pub fn resolve(&self, ch: u8, side: u8) -> Option<&T> {
let ci = ch as usize;
let si = side as usize;
debug_assert!(ci < 2 && si < 2, "channel/side out of range: {ch}, {side}");
let all = self.all.as_set();
let by_ch = self.by_channel.get(ci).and_then(|e| e.cascade(all)).or(all);
self.by_channel_side
.get(ci)
.and_then(|row| row.get(si))
.and_then(|e| e.cascade(by_ch))
}
}
impl<T: Default> Default for Sided<T> {
fn default() -> Self {
Self {
all: Element::Set(T::default()),
by_channel: [Element::Inherit, Element::Inherit],
by_channel_side: [
[Element::Inherit, Element::Inherit],
[Element::Inherit, Element::Inherit],
],
}
}
}