#![cfg(feature = "serde")]
use pie_core::{ElemPool, FibHeap, PieList};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct WorldState {
pool: ElemPool<String>,
active_quests: PieList<String>,
completed_quests: PieList<String>,
}
#[test]
fn test_pielist_roundtrip() {
let mut pool = ElemPool::new();
let mut list = PieList::new(&mut pool);
let compl = PieList::new(&mut pool);
list.push_back("Alpha".to_string(), &mut pool).unwrap();
list.push_back("Beta".to_string(), &mut pool).unwrap();
list.push_back("Gamma".to_string(), &mut pool).unwrap();
let mut original_state = WorldState {
pool: pool, active_quests: list,
completed_quests: compl,
};
let mut pool = ElemPool::new();
let mut l1 = PieList::new(&mut pool);
l1.push_back("Alpha".to_string(), &mut pool).unwrap();
l1.push_back("Beta".to_string(), &mut pool).unwrap();
let mut l2 = PieList::new(&mut pool);
l2.push_back("Done".to_string(), &mut pool).unwrap();
let mut state = WorldState {
pool,
active_quests: l1,
completed_quests: l2,
};
let json = serde_json::to_string(&state).expect("Failed to serialize");
let mut loaded_state: WorldState = serde_json::from_str(&json).expect("Failed to deserialize");
let active: Vec<&String> = loaded_state.active_quests.iter(&loaded_state.pool).collect();
assert_eq!(active, vec!["Alpha", "Beta"]);
let completed: Vec<&String> = loaded_state.completed_quests.iter(&loaded_state.pool).collect();
assert_eq!(completed, vec!["Done"]);
loaded_state.active_quests.push_back("Delta".to_string(), &mut loaded_state.pool).unwrap();
assert_eq!(loaded_state.active_quests.len(), 3);
assert_eq!(*loaded_state.active_quests.back(&loaded_state.pool).unwrap(), "Delta");
original_state.active_quests.set_leak_check(false);
state.active_quests.set_leak_check(false);
state.completed_quests.set_leak_check(false);
loaded_state.active_quests.set_leak_check(false);
loaded_state.completed_quests.set_leak_check(false);
}
#[test]
fn test_fibheap_roundtrip() {
let mut heap = FibHeap::new();
heap.push(10, "Low Priority");
heap.push(1, "High Priority");
heap.push(5, "Medium Priority");
let json = serde_json::to_string(&heap).expect("Failed to serialize heap");
let mut loaded_heap: FibHeap<i32, String> = serde_json::from_str(&json).expect("Failed to deserialize heap");
assert_eq!(loaded_heap.len(), 3);
let (k1, v1) = loaded_heap.pop().unwrap();
assert_eq!(k1, 1);
assert_eq!(v1, "High Priority");
let (k2, v2) = loaded_heap.pop().unwrap();
assert_eq!(k2, 5);
assert_eq!(v2, "Medium Priority");
loaded_heap.push(2, "New Item".to_string());
assert_eq!(loaded_heap.peek().unwrap().0, &2);
}
#[test]
fn test_shrink_before_serialize() {
let mut pool = ElemPool::new();
let mut list = PieList::new(&mut pool);
list.push_back(10, &mut pool).unwrap();
let _idx_remove = list.push_back(20, &mut pool).unwrap(); list.push_back(30, &mut pool).unwrap();
list.pop_front(&mut pool); list.clear(&mut pool);
list.push_back(100, &mut pool).unwrap(); let _idx_rm = list.push_back(200, &mut pool).unwrap(); list.push_back(300, &mut pool).unwrap();
list.pop_front(&mut pool);
let before_cap = pool.capacity();
let map = pool.shrink_to_fit();
list.remap(&map);
#[derive(Serialize, Deserialize)]
struct Container { p: ElemPool<i32>, l: PieList<i32> }
let mut container = Container { p: pool, l: list };
let json = serde_json::to_string(&container).unwrap();
let mut loaded: Container = serde_json::from_str(&json).unwrap();
assert!(loaded.p.capacity() < before_cap);
let vec: Vec<_> = loaded.l.iter(&loaded.p).copied().collect();
assert_eq!(vec, vec![200, 300]);
container.l.set_leak_check(false);
loaded.l.set_leak_check(false);
}
#[test]
fn test_corrupted_freed_count() {
let mut pool = ElemPool::new();
let mut list = PieList::new(&mut pool);
list.push_back(1, &mut pool).unwrap();
#[derive(Serialize, Deserialize)]
struct Container { p: ElemPool<i32>, l: PieList<i32> }
let mut c = Container { p: pool, l: list };
c.l.set_leak_check(false);
let mut json: serde_json::Value = serde_json::to_value(&c).unwrap();
json["p"]["freed"] = serde_json::Value::from(999);
let result: Result<Container, _> = serde_json::from_value(json);
match result {
Err(e) => assert!(e.to_string().contains("freed count mismatch"), "unexpected error: {e}"),
Ok(_) => panic!("should reject mismatched freed count"),
}
}
#[test]
fn test_corrupted_used_count() {
let mut pool = ElemPool::new();
let mut list = PieList::new(&mut pool);
list.push_back(1, &mut pool).unwrap();
#[derive(Serialize, Deserialize)]
struct Container { p: ElemPool<i32>, l: PieList<i32> }
let mut c = Container { p: pool, l: list };
c.l.set_leak_check(false);
let mut json: serde_json::Value = serde_json::to_value(&c).unwrap();
json["p"]["used"] = serde_json::Value::from(0);
let result: Result<Container, _> = serde_json::from_value(json);
match result {
Err(e) => assert!(e.to_string().contains("used count mismatch"), "unexpected error: {e}"),
Ok(_) => panic!("should reject mismatched used count"),
}
}
#[test]
fn test_corrupted_broken_link() {
let mut pool = ElemPool::new();
let mut list = PieList::new(&mut pool);
list.push_back(1, &mut pool).unwrap();
list.push_back(2, &mut pool).unwrap();
#[derive(Serialize, Deserialize)]
struct Container { p: ElemPool<i32>, l: PieList<i32> }
let mut c = Container { p: pool, l: list };
c.l.set_leak_check(false);
let mut json: serde_json::Value = serde_json::to_value(&c).unwrap();
if let Some(elems) = json["p"]["elems"].as_array_mut() {
if let Some(elem) = elems.get_mut(2) {
elem["next"] = serde_json::Value::from(999);
}
}
let result: Result<Container, _> = serde_json::from_value(json);
assert!(result.is_err(), "should reject broken links");
}