Создание CLI в Rust для исполнения гитарных аккордов



Книга Создание CLI в Rust для исполнения гитарных аккордов

Играете на гитаре и вынуждены постоянно искать в интернете аккорды для исполнения песен с менее распространенными аккордами?


А как насчет инструмента командной строки (CLI), который принимает на вход название аккорда и выводит аппликатуру, отображающую способ его исполнения? 


В статье мы реализуем эту идею и с нуля создадим такой CLI в Rust. 


Конечная цель 


Итоговый результат работы  —  создание CLI с именем chord. Он принимает на вход одну строку, а именно название аккорда, и выводит его аппликатуру. Пример: 


$ chord C
x ◯ ◯
┌─┬─┬─┬─┬─┐
│ │ │ │ ◯ │
├─┼─┼─┼─┼─┤
│ │ ◯ │ │ │
├─┼─┼─┼─┼─┤
│ ◯ │ │ │ │
└─┴─┴─┴─┴─┘

Почему Rust? 


Rust выбран не случайно. По результатам опроса Stack Overflow, проведенного в 2021 году, он является самым излюбленным языком программирования: 



Rust отлично подходит как для создания бэкенд-сервисов, так и CLI. 


К делу! 


Установка Rust


Устанавливаем Rust следующим образом: 


$ curl --proto '=https' --tlsv1.2 -sSf <https://sh.rustup.rs> | sh

Более подробная информация по установке предоставлена по ссылке.


Создание нового проекта Rust


$ cargo new chord --bin

Created binary (application) `chord` package

Компилируем и запускаем программу, проверяя корректность всех настроек: 


$ cd chord
$ cargo run


Hello, world!

Полученный результат: 


|-Cargo.toml
|-Cargo.lock
|-src
| |-main.rs

Вывод грифа 


У гитары 6 струн. Как правило, для отображения постановки пальцев используется гриф. 


На данный момент main.rs выглядит так: 


fn main() {
println!("Hello, world!");
}

Внесем в него изменения для вывода пустого грифа: 


const FRETBOARD: &str = "◯ ◯ ◯ ◯ ◯ ◯
┌─┬─┬─┬─┬─┐
│ │ │ │ │ │
├─┼─┼─┼─┼─┤
│ │ │ │ │ │
├─┼─┼─┼─┼─┤
│ │ │ │ │ │
└─┴─┴─┴─┴─┘";

fn main() {
println!("{}", FRETBOARD);
}

Выполняем программу и получаем следующий результат: 


$ cargo run
◯ ◯ ◯ ◯ ◯ ◯
┌─┬─┬─┬─┬─┐
│ │ │ │ │ │
├─┼─┼─┼─┼─┤
│ │ │ │ │ │
├─┼─┼─┼─┼─┤
│ │ │ │ │ │
└─┴─┴─┴─┴─┘

Clap


Для парсинга аргументов командной строки потребуется библиотека Clap.


Присоединяем к проекту Clap в качестве зависимости: 


$ cargo add clap --features derive

Эта команда просто добавляет следующую строку в cargo.toml, где описаны зависимости для Rust: 


clap = { version = "3.2.21", features = ["derive"] }

Обновляем main.rs таким образом: 


const FRETBOARD: &str = "◯ ◯ ◯ ◯ ◯ ◯ 
┌─┬─┬─┬─┬─┐
│ │ │ │ │ │
├─┼─┼─┼─┼─┤
│ │ │ │ │ │
├─┼─┼─┼─┼─┤
│ │ │ │ │ │
└─┴─┴─┴─┴─┘";

use clap::Parser;

/// CLI, показывающий, как сыграть гитарный аккорд
#[derive(Parser, Debug)]
#[clap(version, about)]
struct Args {
/// Название аккорда
#[clap()]
name: String,
}

fn main() {
let args = Args::parse();

println!("This is how you play '{}' chord:
{}", args.name, FRETBOARD);
}

Макросы Rust значительно упрощают для Clap процедуру аннотации Args и обеспечивают бесплатный парсинг аргументов: 


/// CLI, показывающий, как сыграть гитарный аккорд
#[derive(Parser, Debug)]
#[clap(version, about)]
struct Args {
/// Название аккорда
#[clap()]
name: String,
}

Проверяем: 


$ cargo run -- --help

chord 0.1.0
A CLI to show you how to play a guitar chord

USAGE:
chord <NAME>

ARGS:
<NAME> Name of the chord

OPTIONS:
-h, --help Print help information
-V, --version Print version information

$ cargo run -- C

This is how you play 'C' chord:
◯ ◯ ◯ ◯ ◯ ◯
┌─┬─┬─┬─┬─┐
│ │ │ │ │ │
├─┼─┼─┼─┼─┤
│ │ │ │ │ │
├─┼─┼─┼─┼─┤
│ │ │ │ │ │
└─┴─┴─┴─┴─┘

Двойное тире --  —  это общепринятый способ указать на окончание параметров для cargo, а остальное передается программе CLI. Такой принцип действия характерен не только для cargo, но и многих других shell-команд. 


Есть еще одна скрытая особенность, на которую стоит обратить внимание. Заметили, что A CLI to show you how to play a guitar chord (CLI, показывающий, как сыграть гитарный аккорд) и Name of the chord (Название аккорда) являются комментариями в исходном коде? Они также включены в справочное сообщение. 


Из исходного кода:


/// A CLI to show you how to play a guitar chord
#[derive(Parser, Debug)]
#[clap(version, about)]
struct Args {
/// Name of the chord
#[clap()]
name: String,
}

Из вывода:


chord 0.1.0
A CLI to show you how to play a guitar chord

USAGE:
chord <NAME>

ARGS:
<NAME> Name of the chord

Это вся необходимая информация, которую нужно знать о Clap. Переходим непосредственно к самому CLI. 


CLI


Обновляем функцию main следующим образом: 


fn main() {
let args = Args::parse();

let chords: HashMap<&str, &str> =
HashMap::from([("C", "x32010"), ("G", "320003"), ("D", "xx0232")]);

match chords.get(&args.name[..]) {
None => println!("Unknown chord '{}'", args.name),
Some(pattern) => {
let mut board: Vec<char> = FRETBOARD.chars().collect();
for (i, ch) in pattern.chars().enumerate() {
let idx: usize = i * 2;
if ch == 'x' {
board[idx] = ch
} else {
let value: usize = ch.to_digit(10).unwrap() as usize;
board[idx] = ' ';
board[idx + 24 * value] = '◯'
}
}
println!(
"This is how you play '{}' chord:
{}",
args.name,
board.iter().collect::<String>()
)
}
}
}

Если название входного аккорда неизвестно, то выводится сообщение об ошибке Unknown chord. В противном случае мы накладываем постановку пальцев поверх пустого грифа, представленного ранее.


Тестируем код:


$ cargo run -- C                    

This is how you play 'C' chord:
x ◯ ◯
┌─┬─┬─┬─┬─┐
│ │ │ │ ◯ │
├─┼─┼─┼─┼─┤
│ │ ◯ │ │ │
├─┼─┼─┼─┼─┤
│ ◯ │ │ │ │
└─┴─┴─┴─┴─┘

$ cargo run -- Asus4

Unknown chord 'Asus4'

Отличный результат! Быстро и просто!


Установка 


До сих пор мы компилировали и запускали CLI. cargo занимается не только сборкой, выполнением, управлением зависимостями библиотек, но и установкой. 


Устанавливаем CLI chord:


cargo install --path .

И работаем с данным CLI напрямую: 


$ chord G

This is how you play 'G' chord:
◯ ◯ ◯
┌─┬─┬─┬─┬─┐
│ │ │ │ │ │
├─┼─┼─┼─┼─┤
│ ◯ │ │ │ │
├─┼─┼─┼─┼─┤
◯ │ │ │ │ ◯
└─┴─┴─┴─┴─┘

Теперь вы знаете, как создать CLI в Rust. 


Заключение 


Забыли, как сыграть аккорд? Не беда  —  у вас под рукой отличный инструмент.


Переходите по ссылке в ветку blog-post-checkpoint, где предоставлен код для данной статьи. С новейшей версией CLI можно ознакомиться по ссылке на ветке master



725   0  

Comments

    Ничего не найдено.