notation_dsl/core/
pitch_sign.rs

1use fehler::throws;
2
3use notation_proto::prelude::{PitchSign, Semitones};
4use syn::parse::{Error, Parse, ParseStream};
5use syn::Token;
6
7pub struct PitchSignDsl {
8    pub sign: PitchSign,
9}
10
11mod kw {
12    syn::custom_keyword!(b);
13}
14
15impl Parse for PitchSignDsl {
16    #[throws(Error)]
17    fn parse(input: ParseStream) -> Self {
18        let mut semitones: i8 = 0;
19        for _ in 0..2 {
20            if input.peek(Token![#]) {
21                input.parse::<Token![#]>()?;
22                semitones += 1;
23            } else if input.peek(kw::b) {
24                input.parse::<kw::b>()?;
25                semitones -= 1;
26            }
27        }
28        let sign = PitchSign::from(Semitones(semitones));
29        PitchSignDsl { sign }
30    }
31}
32
33impl PitchSignDsl {
34    pub fn peek(input: ParseStream) -> bool {
35        input.peek(Token![#]) || input.peek(Token![%])
36    }
37}