rstmt_core/notes/
note_base.rs1use crate::freq::RawFrequency;
6use crate::octave::Octave;
7use crate::pitch::{self, Pitch, PitchClass};
8
9#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
11#[cfg_attr(
12 feature = "serde",
13 derive(serde::Deserialize, serde::Serialize),
14 serde(deny_unknown_fields, rename_all = "snake_case")
15)]
16#[repr(C)]
17pub struct NoteBase<T, Cls = pitch::C> {
18 pub(crate) class: Cls,
19 pub(crate) octave: Octave,
20 pub(crate) pitch: Pitch<T>,
21}
22
23impl<T, Cls> NoteBase<T, Cls>
24where
25 T: RawFrequency,
26 Cls: PitchClass,
27{
28 pub fn new(pitch: Pitch<T>, octave: Octave) -> Self {
29 Self {
30 class: Cls::new(),
31 octave,
32 pitch,
33 }
34 }
35 pub const fn class(&self) -> &Cls {
37 &self.class
38 }
39 pub const fn octave(&self) -> Octave {
41 self.octave
42 }
43 pub const fn octave_mut(&mut self) -> &mut Octave {
45 &mut self.octave
46 }
47 pub fn set_class(&mut self, class: Cls) -> &mut Self {
49 self.class = class;
50 self
51 }
52 pub fn set_octave(&mut self, octave: Octave) -> &mut Self {
54 self.octave = octave;
55 self
56 }
57 pub fn with_class<Pc: PitchClass>(self) -> NoteBase<T, Pc> {
59 NoteBase {
60 class: Pc::new(),
61 octave: self.octave,
62 pitch: self.pitch,
63 }
64 }
65 pub fn with_octave(self, octave: Octave) -> Self {
67 Self { octave, ..self }
68 }
69}
70
71impl<C, T> core::fmt::Display for NoteBase<T, C>
72where
73 C: PitchClass,
74 T: RawFrequency,
75{
76 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
77 write!(f, "{}.{}", self.class, self.octave)
78 }
79}
80
81impl<T, C> Default for NoteBase<T, C>
82where
83 T: Default,
84 C: PitchClass,
85{
86 fn default() -> Self {
87 Self {
88 class: C::new(),
89 octave: Octave::default(),
90 pitch: Pitch::default(),
91 }
92 }
93}