1use crate::{Interval, Pitch};
2use core::fmt::{self, Write};
3
4#[derive(Clone, Copy, Debug)]
6pub struct Key {
7 sharps: u8,
8}
9
10impl Key {
11 pub fn major(root: Pitch) -> Self {
25 let mut pitch = Pitch::C;
26 let mut alteration = 0;
27 while pitch != root {
28 pitch = pitch + Interval::PERFECT_FIFTH;
29 alteration += 1;
30 }
31
32 Self { sharps: alteration }
33 }
34
35 pub fn sharps(self) -> u8 {
37 self.sharps
38 }
39
40 pub fn flats(self) -> u8 {
42 Pitch::B.into_byte() - self.sharps
43 }
44}
45
46impl fmt::Display for Key {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 if self.sharps <= 6 {
49 for _ in 0..self.sharps {
50 f.write_char('#')?;
51 }
52 } else {
53 for _ in self.sharps..=Pitch::B.into_byte() {
54 f.write_char('b')?;
55 }
56 }
57
58 Ok(())
59 }
60}