pub struct Attributes {
intervals: Vec<u8>
}
impl Attributes {
pub fn new() -> Attributes {
Attributes{intervals: vec![]}
}
fn has(&self, a: &[u8]) -> bool {
a.iter().all(|x| self.intervals.contains(x))
}
pub fn push_interval(&mut self, interval: u8) {
self.intervals.push(interval);
}
pub fn remove(&mut self, i: u8) {
self.intervals = self.intervals.iter()
.filter(|&x| *x != i)
.map(|&x| x)
.collect::<Vec<u8>>();
}
fn resolve_nth(&self) -> String {
let mut val = String::new();
if self.has(&[10]) || self.has(&[11]) {
if self.has(&[11]) {
val.push_str("M");
}
if self.has(&[2,5,9]) {
val.push_str("13");
}
else if self.has(&[2,5]) {
val.push_str("11");
}
else if self.has(&[2]) {
val.push_str("9");
if self.has(&[9]) {
val.push_str("add13");
}
}
else {
val.push_str("7");
if self.has(&[5]) {
val.push_str("add11");
if self.has(&[9]) {
val.push_str(",13");
}
}
else if self.has(&[9]) {
val.push_str("add13");
}
}
}
else {
let mut added = false;
if self.has(&[9]) {
val.push_str("add6");
added = true;
}
if self.has(&[2]) {
if added {
val.push_str(",9");
} else {
val.push_str("add9");
}
added = true;
}
else if self.has(&[5]) {
if added {
val.push_str(",11");
}
else {
val.push_str("add11");
}
added = true;
}
}
val
}
pub fn resolve(&mut self) -> String {
let mut val = String::new();
if self.has(&[4]) || self.has(&[3]) {
if self.has(&[3]) {
if self.has(&[6]) {
if self.has(&[9]) {
self.remove(9);
}
val.push_str("dim");
}
else {
val.push_str("m");
}
}
else {
if self.has(&[6]) {
val.push_str("aug");
}
}
if &val != "dim" && self.has(&[7,9]) {
val.push_str("6");
self.remove(9);
}
}
else if self.has(&[2]) {
val.push_str("sus2");
self.remove(2);
}
else if self.has(&[5]) {
val.push_str("sus4");
self.remove(5);
}
else if self.has(&[7]) {
val.push_str("5");
}
else {
val.push_str("no5");
}
let nth = self.resolve_nth();
if nth.len() > 0 {
if val.len() > 0 && &val != "m" && &val != "dim" {
val.push_str("(");
val.push_str(nth.as_ref());
val.push_str(")");
}
else {
val.push_str(nth.as_ref());
}
}
val
}
}