import EtudeError from "../error/EtudeError"; import EtudeParser from "../util/EtudeParser"; import Exceptional from "../util/Exceptional"; import KeySignature from "./KeySignature"; import Pitch from "./Pitch"; import Value from "./Value"; export default class Note { constructor(private pitch: Pitch, private value: Value) { } public apply(keySignature: KeySignature): Note { const pitch: Pitch = this.pitch.apply(keySignature); if (this.pitch === pitch) { return this; } return new Note(pitch, this.value); } public static fromString(noteString: string): Exceptional { return EtudeParser .of(noteString) .filter(o => o != null, EtudeError.forNull(Note)) .map(s => s.split("[")) .filter(s => s.length >= 2, EtudeError.forInvalid(Note, noteString, "missing information")) .filter(s => s.length <= 2, EtudeError.forInvalid(Note, noteString, "contains extra information")) .filter(s => s[0].trim().length !== 0 && s[1].trim().length !== 0, EtudeError.forInvalid(Note, noteString, "missing information")) .filter(s => s[1].includes("]"), EtudeError.forInvalid(Note, noteString, "missing closing bracket")) .filter(s => s[1].endsWith("]"), EtudeError.forInvalid(Note, noteString, "contains extra information")) .parse(s => Pitch.fromString(s[0])) .parse(s => Value.fromString(s[1].substring(0, s[1].length - 1))) .get(a => new Note(a[0] as Pitch, a[1] as Value)); } public toString(): string { return this.pitch + "[" + this.value + "]"; } public equals(other: any): boolean { if (!(other instanceof Note)) { return false; } if (other === this) { return true; } let otherNote = other as Note; return this.pitch.equals(otherNote.getPitch()) && this.value === otherNote.getValue(); } public getPitch(): Pitch { return this.pitch; } public getValue(): Value { return this.value; } }