Amedeo
SYMBIOSYS OF
PURPOSE & STYLE
Follow us

Search

ekusiadadus
  -  Qiita   -  The World Cup 2022 Rust CLI tool for Japanese football fans!
The World Cup Rust CLI Tool for Japanese Football Fans

I made a CLI tool in Rust to watch the World Cup without being discovered while working.

Hello, @ekusiadadus.
Japan has made it to the finals after unexpectedly finishing first in the group of death.

I want to watch the World Cup: …… But if they find out while I’m at work, they’ll get mad at me: ……

I made a CLI tool to watch the World Cup during work in such a case.
https://github.com/ekusiadadus/samuraicup

(We lost by PK just now 😢)

How to use

🌸 World Cup 2022 CLI for Japanese football fans 🌸

Usage: samuraicli <COMMAND>

Commands:
  real ⚽Check the World Cup in real time
  search 🥅Get World Cup tweets
  keisuke 📣Get Keisuke Honda's movement
  help Print this message or the help of the given subcommand(s)

Options:
  -h, --help Print help information

Video moved during the Croatia match on December 6

How to make

It is designed, but the part to get tweets is made in a clean architecture way. (It may be quite quirky.)

The CLI part and so on are simply written in main.rs.
I used clap to create the CLI tools.
Characters are colored randomly using owo-colors.

1. using Twitter API

We used Twitter API to retrieve World Cup tweets.
I wrote about this area in Analyzing Twitter with BigQuery and JupyterLab ~ Twitter API v2 ~. Please refer to that article.

2. creating a CLI tool in Rust

I used clap to create a CLI tool.

You can pass options in a nice way as follows.

fn cli() -> Command {
    Command::new("samuraicup")
        .about("🌸 World Cup 2022 CLI for Japanese football fans 🌸")
        .subcommand_required(true)
        .arg_required_else_help(true)
        .allow_external_subcommands(true)
        .subcommand(Command::new("real").about("⚽ worldcaps in real time"))
        .subcommand(Command::new("search").about("🥅Get World Cup tweets"))
        .subcommand(Command::new("keisuke").about("📣Get Keisuke Honda's movement"))
}

The value received here is branched out with match to execute the process.

When I wrote the process of receiving tweets, I wrote asynchronous processing using tokio.
This area is written in a clean architecture style (I think).

async fn main() -> Result<(), Box<dyn std::error::Error>> {
    std::env::set_var("RUST_LOG", "info");
    std::env::set_var("RUST_BACKTRACE", "1");
    dotenv().ok();

    let db_url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    let db_pool_size = std::env::var("DATABASE_POOL_SIZE")
        .ok()
        .and_then(|it| it.parse().ok())
        .unwrap_or(5);
    let bearer_token = std::env::var("BEARER_TOKEN").expect("BEARER_TOKEN not set");

    let app = initializer::new(initializer::Config {
        db_url: db_url,
        db_pool_size: db_pool_size,
        bearer_token: bearer_token,
    })
    .await;

    app.infras
        .ensure_initialized()
        .await
        .expect("Infra initialization error");

    let matches = cli().get_matches();

Summary

Now I can watch the World Cup at work without being detected!

… Oh, it doesn’t matter because I’m remote.
Let’s watch TV.
I’ll be cheering for England.

Translated with www.DeepL.com/Translator (free version)

Leave a Comment