use super::types::Item;
#[derive(Debug, Clone, issun_macros::Service)]
#[service(name = "inventory_service")]
pub struct InventoryService;
impl InventoryService {
pub fn new() -> Self {
Self
}
pub fn transfer_item<T: Item>(from: &mut Vec<T>, to: &mut Vec<T>, index: usize) -> Option<T> {
if index >= from.len() {
return None;
}
let item = from.remove(index);
to.push(item.clone());
Some(item)
}
pub fn equip_item<T: Item>(current: &mut T, new_item: T) -> T {
std::mem::replace(current, new_item)
}
pub fn consume_item<T: Item>(inventory: &mut Vec<T>, index: usize) -> Option<T> {
if index >= inventory.len() {
return None;
}
Some(inventory.remove(index))
}
pub fn add_item<T: Item>(inventory: &mut Vec<T>, item: T) {
inventory.push(item);
}
pub fn remove_item<T: Item>(inventory: &mut Vec<T>, index: usize) -> bool {
if index >= inventory.len() {
return false;
}
inventory.remove(index);
true
}
pub fn inventory_size<T: Item>(inventory: &[T]) -> usize {
inventory.len()
}
pub fn is_empty<T: Item>(inventory: &[T]) -> bool {
inventory.is_empty()
}
}
impl Default for InventoryService {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(Clone, Debug, PartialEq, Eq)]
struct MockItem {
name: String,
value: i32,
}
#[test]
fn test_transfer_item() {
let mut from = vec![
MockItem {
name: "Sword".to_string(),
value: 100,
},
MockItem {
name: "Shield".to_string(),
value: 50,
},
];
let mut to = Vec::new();
let transferred = InventoryService::transfer_item(&mut from, &mut to, 0);
assert!(transferred.is_some());
assert_eq!(transferred.unwrap().name, "Sword");
assert_eq!(from.len(), 1);
assert_eq!(to.len(), 1);
assert_eq!(to[0].name, "Sword");
}
#[test]
fn test_transfer_item_invalid_index() {
let mut from = vec![MockItem {
name: "Sword".to_string(),
value: 100,
}];
let mut to = Vec::new();
let result = InventoryService::transfer_item(&mut from, &mut to, 10);
assert!(result.is_none());
assert_eq!(from.len(), 1);
assert_eq!(to.len(), 0);
}
#[test]
fn test_equip_item() {
let mut current = MockItem {
name: "Old Sword".to_string(),
value: 50,
};
let new = MockItem {
name: "New Sword".to_string(),
value: 100,
};
let old = InventoryService::equip_item(&mut current, new);
assert_eq!(old.name, "Old Sword");
assert_eq!(current.name, "New Sword");
}
#[test]
fn test_consume_item() {
let mut inventory = vec![
MockItem {
name: "Potion".to_string(),
value: 20,
},
MockItem {
name: "Elixir".to_string(),
value: 50,
},
];
let consumed = InventoryService::consume_item(&mut inventory, 0);
assert!(consumed.is_some());
assert_eq!(consumed.unwrap().name, "Potion");
assert_eq!(inventory.len(), 1);
assert_eq!(inventory[0].name, "Elixir");
}
#[test]
fn test_add_item() {
let mut inventory = Vec::new();
let item = MockItem {
name: "Sword".to_string(),
value: 100,
};
InventoryService::add_item(&mut inventory, item);
assert_eq!(inventory.len(), 1);
assert_eq!(inventory[0].name, "Sword");
}
#[test]
fn test_remove_item() {
let mut inventory = vec![MockItem {
name: "Sword".to_string(),
value: 100,
}];
let result = InventoryService::remove_item(&mut inventory, 0);
assert!(result);
assert_eq!(inventory.len(), 0);
}
#[test]
fn test_inventory_size() {
let inventory = vec![
MockItem {
name: "Sword".to_string(),
value: 100,
},
MockItem {
name: "Shield".to_string(),
value: 50,
},
];
assert_eq!(InventoryService::inventory_size(&inventory), 2);
}
#[test]
fn test_is_empty() {
let empty: Vec<MockItem> = Vec::new();
let non_empty = vec![MockItem {
name: "Sword".to_string(),
value: 100,
}];
assert!(InventoryService::is_empty(&empty));
assert!(!InventoryService::is_empty(&non_empty));
}
}