rstmt_core/notes/impls/
impl_note_ext.rs

1/*
2    Appellation: impl_note_ext <module>
3    Created At: 2025.12.31:18:23:09
4    Contrib: @FL03
5*/
6use crate::notes::note_base::NoteBase;
7use crate::octave::Octave;
8use crate::pitch::{Accidental, PitchClass, PitchClassRepr, RawPitchClass};
9#[cfg(feature = "alloc")]
10use alloc::vec::Vec;
11
12impl<P, K> core::fmt::Debug for NoteBase<P, K>
13where
14    P: RawPitchClass<Tag = K>,
15    K: Accidental,
16{
17    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
18        f.write_str(self.aspn().as_str())
19    }
20}
21
22impl<P, K> core::fmt::Display for NoteBase<P, K>
23where
24    P: RawPitchClass<Tag = K>,
25    K: Accidental,
26{
27    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
28        f.write_str(self.aspn().as_str())
29    }
30}
31
32impl<P, K> PartialEq<str> for NoteBase<P, K>
33where
34    P: RawPitchClass<Tag = K>,
35    K: Accidental,
36{
37    fn eq(&self, other: &str) -> bool {
38        self.aspn() == other
39    }
40}
41
42impl<P, K> PartialEq<&str> for NoteBase<P, K>
43where
44    P: RawPitchClass<Tag = K>,
45    K: Accidental,
46{
47    fn eq(&self, other: &&str) -> bool {
48        self.aspn() == *other
49    }
50}
51
52#[cfg(feature = "alloc")]
53impl<P, K> core::str::FromStr for NoteBase<P, K>
54where
55    P: PitchClassRepr<Tag = K>,
56    K: Accidental + core::str::FromStr<Err = crate::Error>,
57{
58    type Err = crate::Error;
59
60    fn from_str(s: &str) -> Result<Self, Self::Err> {
61        let parts: Vec<&str> = s.split('.').collect();
62        if parts.len() != 2 {
63            return Err(crate::Error::FromStrParseError);
64        }
65        let lex_class = parts[0];
66        let lex_octave = parts[1];
67        let class = lex_class.parse::<PitchClass<P, K>>()?;
68        let octave = lex_octave.parse::<isize>().expect("Failed to parse octave");
69        Ok(Self::new(class, Octave(octave)))
70    }
71}