1use crate::{Natural, Pitch};
2use core::marker::PhantomData;
3
4mod accidental;
5pub use accidental::{Accidental, AccidentalKind, Flat, Sharp};
6
7#[derive(Debug, PartialEq, Eq)]
8pub struct Note<A> {
9 natural: Natural,
10 accidental_kind: AccidentalKind,
11 _accidental: PhantomData<A>,
12}
13
14impl<A> Note<A> {
15 pub fn new(natural: Natural, accidental: AccidentalKind) -> Self {
16 Self {
17 natural,
18 accidental_kind: accidental,
19 _accidental: PhantomData,
20 }
21 }
22
23 pub fn natural(self) -> Natural {
24 self.natural
25 }
26
27 pub fn natural_mut(&mut self) -> &mut Natural {
28 &mut self.natural
29 }
30
31 pub fn accidental(self) -> AccidentalKind {
32 self.accidental_kind
33 }
34
35 pub fn accidental_mut(&mut self) -> &mut AccidentalKind {
36 &mut self.accidental_kind
37 }
38}
39
40impl Note<Flat> {
41 pub fn flat(natural: Natural) -> Self {
42 Self::new(natural, AccidentalKind::Single)
43 }
44
45 pub fn double_flat(natural: Natural) -> Self {
46 Self::new(natural, AccidentalKind::Double)
47 }
48}
49
50impl Note<Sharp> {
51 pub fn sharp(natural: Natural) -> Self {
52 Self::new(natural, AccidentalKind::Single)
53 }
54
55 pub fn double_sharp(natural: Natural) -> Self {
56 Self::new(natural, AccidentalKind::Double)
57 }
58}
59
60impl<A> Clone for Note<A> {
61 fn clone(&self) -> Self {
62 Self::new(self.natural, self.accidental_kind)
63 }
64}
65
66impl<A> Copy for Note<A> {}
67
68impl<A> From<Note<A>> for Pitch
69where
70 A: Accidental,
71{
72 fn from(note: Note<A>) -> Self {
73 A::into_pitch(note.accidental_kind, note.natural)
74 }
75}
76
77impl<A> From<Natural> for Note<A> {
78 fn from(natural: Natural) -> Self {
79 Self::new(natural, AccidentalKind::Natural)
80 }
81}