Skip to content

Commit

Permalink
Add infra for commands
Browse files Browse the repository at this point in the history
  • Loading branch information
maxwellmattryan committed Oct 31, 2024
1 parent 7dca1e1 commit 55b779f
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 7 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ authors = ["Matthew Maxwell"]
description = "CLI tool for converting frequencies and musical notes"

[dependencies]
async-trait = "0.1.83"
regex = "1.11.1"
structopt = "0.3.26"
thiserror = "1.0.65"
tokio = { version = "1.41.0", features = ["full"] }
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# `fnote`

[![Format](https://github.com/blackboxaudio/fnote/actions/workflows/ci.fmt.yml/badge.svg)](https://github.com/blackboxaudio/fnote/actions/workflows/ci.fmt.yml)
[![Lint](https://github.com/blackboxaudio/fnote/actions/workflows/ci.lint.yml/badge.svg)](https://github.com/blackboxaudio/fnote/actions/workflows/ci.lint.yml)
[![Format](https://github.com/blackboxaudio/fnote/actions/workflows/ci.fmt.yml/badge.svg)](https://github.com/blackboxaudio/fnote/actions/workflows/ci.fmt.yml)
[![Version: v0.1.0](https://img.shields.io/badge/Version-v0.1.0-blue.svg)](https://github.com/blackboxaudio/fnote)
[![License](https://img.shields.io/badge/License-MIT-yellow)](https://github.com/blackboxaudio/fnote/blob/develop/LICENSE)

Expand Down
30 changes: 30 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use async_trait::async_trait;

use crate::{commands::midi::MidiCommand, error::FNoteResult};

/// Represents an `fnote` program command.
#[async_trait]
pub trait Command {
/// Executes the corresponding command.
async fn run(&self) -> FNoteResult<()>;
}

/// Commands supported by `fnote`.
#[derive(structopt::StructOpt)]
#[structopt(
author = "Matthew Maxwell",
version = env!("CARGO_PKG_VERSION"),
)]
pub enum FNoteCommand {
/// Extracts the frequency and musical note from a MIDI note number (0-127).
Midi(MidiCommand),
}

#[async_trait]
impl Command for FNoteCommand {
async fn run(&self) -> FNoteResult<()> {
match self {
Self::Midi(cmd) => cmd.run().await,
}
}
}
34 changes: 34 additions & 0 deletions src/commands/midi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use async_trait::async_trait;
use regex::Regex;

use crate::{
cli::Command,
error::{FNoteError, FNoteResult},
};

/// Extracts the frequency and musical note from a MIDI note number (0-127).
#[derive(structopt::StructOpt)]
pub struct MidiCommand {
/// The MIDI note number to use.
#[structopt(parse(try_from_str = try_midi_note_number_from_str))]
pub midi_note_number: usize,
}

#[async_trait]
impl Command for MidiCommand {
async fn run(&self) -> FNoteResult<()> {
println!("Converting MIDI note number: {:?}", self.midi_note_number);

Ok(())
}
}

/// Parses a MIDI note number from a string.
fn try_midi_note_number_from_str(arg: &str) -> FNoteResult<usize> {
let regex = Regex::new(r"^(?:\d|[1-9]\d|1[01]\d|12[0-7])$").unwrap();
if regex.is_match(arg) {
Ok(arg.parse::<usize>().unwrap())
} else {
Err(FNoteError::InvalidMidiNoteNumber(arg.to_string()))
}
}
1 change: 1 addition & 0 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub(crate) mod midi;
8 changes: 7 additions & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,10 @@ pub type FNoteResult<T> = std::result::Result<T, FNoteError>;

/// Error variants for the `fnote` program.
#[derive(Debug, PartialEq, thiserror::Error)]
pub enum FNoteError {}
pub enum FNoteError {
#[error("Unknown command")]
UnknownCommand,

#[error("Invalid MIDI note number \"{0}\"")]
InvalidMidiNoteNumber(String),
}
5 changes: 4 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
pub(crate) mod error;
pub mod cli;
pub mod error;

pub(crate) mod commands;
13 changes: 9 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
use crate::error::FNoteResult;

mod error;
use fnote::{
cli::{Command, FNoteCommand},
error::{FNoteError, FNoteResult},
};
use structopt::StructOpt;

#[tokio::main]
async fn main() -> FNoteResult<()> {
Ok(())
match FNoteCommand::from_args().run().await {
Ok(_) => Ok(()),
Err(_) => panic!("{:?}", FNoteError::UnknownCommand),
}
}

0 comments on commit 55b779f

Please sign in to comment.