use crate::{RowFamily, RowForm, RowOperation, ToneRow};
const FAMILIES: [RowFamily; 4] = [RowFamily::P, RowFamily::I, RowFamily::R, RowFamily::RI];
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RowAlias {
pub operation: RowOperation,
pub form: RowForm,
distinct_form_index: usize,
}
impl RowAlias {
pub const fn distinct_form_index(&self) -> usize {
self.distinct_form_index
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RowFamilySet {
source: ToneRow,
aliases: Vec<RowAlias>,
distinct_forms: Vec<ToneRow>,
}
impl RowFamilySet {
pub fn of(source: &ToneRow) -> Self {
let mut aliases = Vec::with_capacity(48);
let mut distinct_forms = Vec::with_capacity(48);
for family in FAMILIES {
for addend in 0..12 {
let operation = RowOperation::new(family, addend);
let form = source.apply(operation);
let distinct_form_index = distinct_forms
.iter()
.position(|distinct| distinct == form.row())
.unwrap_or_else(|| {
distinct_forms.push(form.row().clone());
distinct_forms.len() - 1
});
aliases.push(RowAlias {
operation,
form,
distinct_form_index,
});
}
}
Self {
source: source.clone(),
aliases,
distinct_forms,
}
}
pub const fn source(&self) -> &ToneRow {
&self.source
}
pub fn aliases(&self) -> &[RowAlias] {
&self.aliases
}
pub fn distinct_forms(&self) -> &[ToneRow] {
&self.distinct_forms
}
pub fn aliases_for_distinct_form(
&self,
distinct_form_index: usize,
) -> impl Iterator<Item = &RowAlias> {
self.aliases.iter().filter(move |alias| {
alias.distinct_form_index == distinct_form_index
&& distinct_form_index < self.distinct_forms.len()
})
}
}