use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
pub struct Item {
pub id: u32,
pub name: String,
}
pub type Db = Arc<Mutex<HashMap<u32, Item>>>;
pub fn create_item(db: &Db, item: Item) -> Result<(), String> {
let mut db = db.lock().unwrap();
if db.contains_key(&item.id) {
return Err("Item with this ID already exists".to_string());
}
db.insert(item.id, item);
Ok(())
}
pub fn read_items(db: &Db) -> Vec<Item> {
let db = db.lock().unwrap();
db.values().cloned().collect()
}
pub fn update_item(db: &Db, id: u32, name: String) -> Result<(), String> {
let mut db = db.lock().unwrap();
if let Some(item) = db.get_mut(&id) {
item.name = name;
Ok(())
} else {
Err("Item not found".to_string())
}
}
pub fn delete_item(db: &Db, id: u32) -> Result<(), String> {
let mut db = db.lock().unwrap();
if db.remove(&id).is_some() {
Ok(())
} else {
Err("Item not found".to_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
fn create_test_db() -> Db {
Arc::new(Mutex::new(HashMap::new()))
}
#[test]
fn test_create_item() {
let db = create_test_db();
let item = Item {
id: 1,
name: "Test Item".to_string(),
};
assert!(create_item(&db, item.clone()).is_ok());
assert!(create_item(&db, item).is_err());
}
#[test]
fn test_read_items() {
let db = create_test_db();
let item1 = Item {
id: 1,
name: "Item 1".to_string(),
};
let item2 = Item {
id: 2,
name: "Item 2".to_string(),
};
create_item(&db, item1.clone()).unwrap();
create_item(&db, item2.clone()).unwrap();
let items = read_items(&db);
assert_eq!(items.len(), 2);
assert!(items.contains(&item1));
assert!(items.contains(&item2));
}
#[test]
fn test_update_item() {
let db = create_test_db();
let item = Item {
id: 1,
name: "Old Name".to_string(),
};
create_item(&db, item.clone()).unwrap();
assert!(update_item(&db, 1, "New Name".to_string()).is_ok());
let updated_item = db.lock().unwrap().get(&1).unwrap().clone();
assert_eq!(updated_item.name, "New Name");
assert!(update_item(&db, 2, "Another Name".to_string()).is_err());
}
#[test]
fn test_delete_item() {
let db = create_test_db();
let item = Item {
id: 1,
name: "Test Item".to_string(),
};
create_item(&db, item.clone()).unwrap();
assert!(delete_item(&db, 1).is_ok());
assert!(db.lock().unwrap().get(&1).is_none());
assert!(delete_item(&db, 2).is_err());
}
}