• Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

Building a Decision-Making CLI Tool in Rust: "should-i"

Sascha Оффлайн

Sascha

Заместитель Администратора
Команда форума
Администратор
Регистрация
9 Май 2015
Сообщения
1,605
Баллы
155
Introduction


"What should I have for lunch?" "Should I try this new library?" From daily small decisions to technical choices, we face countless decisions every day. Why not let the universe decide for you?

I built a CLI tool called "should-i" that helps you make decisions by consulting the

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

. In this article, I'll share the implementation details and technical insights.

What is should-i?


should-i is a simple CLI tool that answers your questions with YES/NO/MAYBE. It also returns a GIF image URL, making the experience more engaging and visual.

Basic Usage



Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Browser GIF Display with --open Option


With the --open option, the tool automatically opens the response GIF in your browser:


$ should-i "take a coffee break" --open
🎲 Asking the universe...
✅ YES! Do it! 🎉
🖼

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.


# Browser opens with the GIF automatically



Tech Stack


This project uses the following Rust crates:

  • reqwest: HTTP client
  • tokio: Async runtime
  • serde/serde_json: JSON serialization/deserialization
  • clap: CLI argument parser
  • anyhow: Error handling
  • webbrowser: Browser opening functionality
Implementation Highlights

1. API Communication


The yesno.wtf API is a simple RESTful API with responses structured like this:


{
"answer": "yes",
"forced": false,
"image": "

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

"
}




We map this to a Rust struct:


#[derive(Deserialize)]
struct YesNoResponse {
answer: String,
image: String,
}




Making async HTTP requests with reqwest is simple and type-safe:


let response = client
.get("

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

")
.send()
.await?
.json::()
.await?;



2. CLI Interface Design


Using clap makes implementing an intuitive CLI straightforward. The derive macro approach is very Rust-like, automatically generating a parser from struct definitions:


#[derive(Parser)]
#[command(name = "should-i")]
#[command(about = "A CLI tool to help you make decisions")]
struct Cli {
/// The question you want to ask
question: String,

/// Open the GIF image in your browser
#[arg(short, long)]
open: bool,
}



3. Enhancing User Experience


Rather than just displaying results, I used emojis to make the output visually clear and engaging:


match response.answer.as_str() {
"yes" => println!("✅ YES! Do it! 🎉"),
"no" => println!("❌ NO! Don't do it! 🚫"),
"maybe" => println!("🤔 MAYBE... You decide! 🎲"),
_ => println!("🤷 Unknown response"),
}




The --open option automatically opens the GIF in your browser:


if cli.open {
if let Err(e) = webbrowser::open(&response.image) {
eprintln!("⚠ Failed to open browser: {}", e);
}
}




This feature lets you visually enjoy the universe's message, which is one of the tool's charms.

Error Handling


Leveraging Rust's powerful type system, I implemented proper error handling using the anyhow crate:


async fn fetch_decision() -> anyhow::Result {
let client = reqwest::Client::new();
let response = client
.get("

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

")
.send()
.await
.context("Failed to connect to yesno.wtf API")?
.json::()
.await
.context("Failed to parse API response")?;

Ok(response)
}




The context() method provides specific context when errors occur.

Project Structure


should-i/
├── Cargo.toml # Dependencies and metadata
├── src/
│ └── main.rs # Main implementation
├── LICENSE-MIT
├── LICENSE-APACHE
└── README.md




As a simple tool, everything is contained in a single file. For larger projects, consider splitting into modules.

Installation

Using Cargo


cargo install should-i



Using Homebrew


brew tap Justhiro55/tap
brew install should-i



From Source


git clone

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.


cd should-i
cargo install --path .



Conclusion


should-i is simple, but it contains fundamental elements of Rust CLI development:

  • Async HTTP communication
  • JSON parsing
  • CLI argument handling
  • Error handling
  • Cross-platform support

The playful concept of "letting the universe decide" made implementing practical Rust techniques enjoyable.

When in doubt, just ask should-i!


$ should-i "write more Rust code"
🎲 Asking the universe...
✅ YES! Do it! 🎉



Links



Источник:

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

 
Вверх Снизу