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