From be9bdd235c75448890178e30e9dc156acbd6f8e2 Mon Sep 17 00:00:00 2001 From: Matthew Maxwell Date: Wed, 30 Oct 2024 19:28:15 -0500 Subject: [PATCH] Add stubbed command for notes --- src/cli.rs | 11 +++++++++-- src/commands/midi.rs | 2 +- src/commands/mod.rs | 1 + src/commands/note.rs | 34 ++++++++++++++++++++++++++++++++++ src/error.rs | 3 +++ 5 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 src/commands/note.rs diff --git a/src/cli.rs b/src/cli.rs index cd874d6..b8a7c07 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,6 +1,9 @@ use async_trait::async_trait; -use crate::{commands::midi::MidiCommand, error::FNoteResult}; +use crate::{ + commands::{midi::MidiCommand, note::NoteCommand}, + error::FNoteResult, +}; /// Represents an `fnote` program command. #[async_trait] @@ -16,8 +19,11 @@ pub trait Command { version = env!("CARGO_PKG_VERSION"), )] pub enum FNoteCommand { - /// Extracts the frequency and musical note from a MIDI note number (0-127). + /// Extracts the frequency and music note from a MIDI note number (0-127). Midi(MidiCommand), + + /// Extracts the frequency and MIDI note number from a music note (e.g. C5). + Note(NoteCommand), } #[async_trait] @@ -25,6 +31,7 @@ impl Command for FNoteCommand { async fn run(&self) -> FNoteResult<()> { match self { Self::Midi(cmd) => cmd.run().await, + Self::Note(cmd) => cmd.run().await, } } } diff --git a/src/commands/midi.rs b/src/commands/midi.rs index 5d586bd..e387742 100644 --- a/src/commands/midi.rs +++ b/src/commands/midi.rs @@ -6,7 +6,7 @@ use crate::{ error::{FNoteError, FNoteResult}, }; -/// Extracts the frequency and musical note from a MIDI note number (0-127). +/// Extracts the frequency and music note from a MIDI note number (0-127). #[derive(structopt::StructOpt)] pub struct MidiCommand { /// The MIDI note number to use. diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 911a759..ae58a65 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1 +1,2 @@ pub(crate) mod midi; +pub(crate) mod note; diff --git a/src/commands/note.rs b/src/commands/note.rs new file mode 100644 index 0000000..d98b37b --- /dev/null +++ b/src/commands/note.rs @@ -0,0 +1,34 @@ +use async_trait::async_trait; +use regex::Regex; + +use crate::{ + cli::Command, + error::{FNoteError, FNoteResult}, +}; + +/// Extracts the frequency and MIDI note number from a music note (e.g. C5). +#[derive(structopt::StructOpt)] +pub struct NoteCommand { + /// The music note to use. + #[structopt(parse(try_from_str = try_music_note_from_str))] + pub musical_note: String, +} + +#[async_trait] +impl Command for NoteCommand { + async fn run(&self) -> FNoteResult<()> { + println!("Converting music note: {:?}", self.musical_note); + + Ok(()) + } +} + +/// Parses a music note from a string. +fn try_music_note_from_str(arg: &str) -> FNoteResult { + let regex = Regex::new(r"^[A-Ga-g][#b]?[0-9]$").unwrap(); + if regex.is_match(arg) { + Ok(arg.to_string()) + } else { + Err(FNoteError::InvalidMusicNote(arg.to_string())) + } +} diff --git a/src/error.rs b/src/error.rs index 60348b5..5ed95e7 100644 --- a/src/error.rs +++ b/src/error.rs @@ -9,4 +9,7 @@ pub enum FNoteError { #[error("Invalid MIDI note number \"{0}\"")] InvalidMidiNoteNumber(String), + + #[error("Invalid music note \"{0}\"")] + InvalidMusicNote(String), }