🦀/100 Projects/Notes/Source

src/main.rs

View on GitHub
use std::collections::HashMap;
use std::fs::{File, OpenOptions};
use std::io::{self, BufReader, Write};
use serde::{Deserialize, Serialize};

const STORE_FILE: &str = "kv_store.json";

#[derive(Serialize, Deserialize)]
struct Store {
    data: HashMap<String, String>,
}

impl Store {
    fn new() -> Self {
        if let Ok(file) = File::open(STORE_FILE) {
            let reader = BufReader::new(file);
            if let Ok(store) = serde_json::from_reader(reader) {
                return store;
            }
        }
        Store { data: HashMap::new() }
    }

    fn save(&self) {
        if let Ok(mut file) = OpenOptions::new()
            .write(true)
            .create(true)
            .truncate(true)
            .open(STORE_FILE)
        {
            serde_json::to_writer_pretty(&mut file, self).unwrap();
        }
    }

    fn set(&mut self, key: String, value: String) {
        self.data.insert(key, value);
        self.save();
    }

    fn get(&self, key: &str) -> Option<&String> {
        self.data.get(key)
    }

    fn delete(&mut self, key: &str) {
        self.data.remove(key);
        self.save();
    }

    fn list(&self) {
        println!("📦 Stored Keys:");
        for key in self.data.keys() {
            println!("- {}", key);
        }
    }
}

fn main() {
    println!("🗃️ Key-Value Store (set/get/delete/list/exit)");
    let mut store = Store::new();

    loop {
        let cmd = prompt("\n> ");
        let parts: Vec<&str> = cmd.trim().splitn(3, ' ').collect();

        match parts.as_slice() {
            ["set", key, value] => {
                store.set(key.to_string(), value.to_string());
                println!("✅ Key set.");
            }
            ["get", key] => match store.get(key) {
                Some(value) => println!("🔑 Value: {}", value),
                None => println!("❌ Key not found."),
            },
            ["delete", key] => {
                store.delete(key);
                println!("🗑️ Key deleted (if it existed).");
            }
            ["list"] => store.list(),
            ["exit"] => {
                println!("👋 Exiting.");
                break;
            }
            _ => println!("❌ Invalid command. Use: set/get/delete/list/exit"),
        }
    }
}

fn prompt(msg: &str) -> String {
    print!("{}", msg);
    io::stdout().flush().unwrap();
    let mut buffer = String::new();
    io::stdin().read_line(&mut buffer).unwrap();
    buffer.trim().to_string()
}

← Back to folder