notation_dsl/core/
pitch_sign.rs1use 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}