Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

練習用にアドレス帳みたいなのをつくる その1:とりあえずサブコマンドを受け取って保存する

練習用にアドレス帳みたいなのを作ります
まずはClapで

実際のところ

tomlファイル

[package]
name = "newproject"
version = "0.1.0"
edition = "2021"

[build]
name = "newproject"
path = "src/main.rs"

[dependencies]
clap = { version = "4.4", features = ["derive"] }

スクリプト

use std::error::Error;
use clap::{Parser, Subcommand};

#[derive(Debug, Parser)] 
#[command(author, version, about)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Debug, Subcommand)]
enum Commands {
    Add {
        #[clap(value_parser)]
        name: String,
        #[clap(value_parser)]
        email: String,
        #[clap(value_parser)]
        age: u8,
    },
}

#[derive(Debug)] 
// データ構造を表現するstruct
// 構造はprivateなもので、ユーザーは意識しないで済む
struct User {
    name: String,
    email: String,
    age: u8,
}


// データベースの役割を果たす構造体を追加
#[derive(Debug, Default)]
struct UserDatabase {
    users: Vec<User>
}

impl UserDatabase {
    fn new() -> Self {
        UserDatabase { users: Vec::new() }
    }

    fn add_user(&mut self, user: User) -> Result<(), String> {
        // メールアドレスの重複チェック
        if self.users.iter().any(|u| u.email == user.email) {
            return Err("Email already exists".to_string());
        }
        self.users.push(user);
        Ok(())
    }
}

fn main() {
    let args = Cli::parse();
    let mut db = UserDatabase::new();

    match args.command {    
        Commands::Add { name, email, age } => {
            let user = User {
                name: String::from(name),
                email: String::from(email),
                age,
            };

            match db.add_user(user) {
                Ok(_) => println!("User added successfully"),
                Err(e) => println!("Failed to add user: {}", e),
            }

            // データベースの現在の状態を表示
            println!("Current database state: {:?}", db);
        }
    }   
}

実行してみる

$ .\newproject add "sample" "sample2@example.com" 25
User added successfully
Current database state: UserDatabase { users: [User { name: "sample", email: "sample2@example.com", age: 25 }] }

参考もと