use std::error; use std::mem; use rod::*; #[allow(dead_code)] #[derive(Clone, Debug, Eq, PartialEq)] struct TestStructA { prop_1: i32, prop_2: String, } #[allow(dead_code)] #[derive(Clone, Debug, Eq, PartialEq)] struct TestStructB { prop_1: i32, prop_2: String, prop_3: bool, } #[test] fn store() -> Result<(), Box> { let store = Store::new(); let test_struct_a_1 = TestStructA { prop_1: 1, prop_2: "".into() }; let test_struct_a_2 = test_struct_a_1.clone(); let test_sturct_a_3 = test_struct_a_1.clone(); let test_struct_b = TestStructB { prop_1: 1, prop_2: "".into(), prop_3: true }; let key_1 = 5; let key_2 = 10; store.store(key_1, test_struct_a_1).expect("should be able to store an item"); assert_eq!( mem::discriminant(&store.store(key_1, test_struct_a_2).expect_err("should throw error when storing an item with a duplicate key")), mem::discriminant(&StoreError::Existing), "error type should be Existing when storing an item with a duplicate key", ); store.store(key_2, test_sturct_a_3).expect("should be able to store an item with the same type but a different key"); store.store(key_1, test_struct_b).expect("should be able to store an item with a duplicate key but a different type"); Ok(()) } #[test] fn lock() -> Result<(), Box> { let store = Store::new(); let test_struct_a_1 = TestStructA { prop_1: 1, prop_2: "1".into() }; let test_struct_a_2 = TestStructA { prop_1: 2, prop_2: "2".into() }; let test_struct_a_1_clone = test_struct_a_1.clone(); let test_struct_b = TestStructB { prop_1: 3, prop_2: "3".into(), prop_3: true }; let key_1 = 5; let key_2 = 10; store.lock::<_, TestStructA>(key_1).err().expect("shouldn't be able to lock when the item doesn't exist"); store.store(key_1, test_struct_a_1)?; store.store(key_2, test_struct_a_2)?; store.store(key_1, test_struct_b)?; let mut test_struct_a_1_lock = store.lock::<_, TestStructA>(key_1).expect("should be able to lock when the item exists"); assert_eq!(*test_struct_a_1_lock, test_struct_a_1_clone, "struct lock should dereference to the stored struct"); assert_eq!( mem::discriminant(&store.lock::<_, TestStructA>(key_1).err().expect("shouldn't be able to lock when it's already locked")), mem::discriminant(&LockError::Locked), "error type should be Locked when trying to lock an item that is already locked" ); store.lock::<_, TestStructA>(key_2).expect("should be able to lock an item with the same type but a different key"); store.lock::<_, TestStructB>(key_1).expect("should be able to lock an item with the same key but a different type"); test_struct_a_1_lock.prop_1 = 10; drop(test_struct_a_1_lock); let test_struct_a_1_ref = store.borrow::<_, TestStructA>(key_1)?; assert_eq!(test_struct_a_1_ref.prop_1, 10, "the changes made to the struct through the lock should persist after the lock is dropped"); Ok(()) } #[test] fn borrow() -> Result<(), Box> { let store = Store::new(); let test_struct = TestStructA { prop_1: 1, prop_2: "".into() }; let test_struct_clone = test_struct.clone(); let key = 5; store.borrow::<_, TestStructA>(key).err().expect("shouldn't be able to borrow when the item doesn't exist"); store.store(key, test_struct)?; let test_struct_ref1 = store.borrow::<_, TestStructA>(key).expect("should be able to borrow an item"); let test_struct_ref2 = store.borrow::<_, TestStructA>(key).expect("should be able to borrow an item multiple times"); assert_eq!(*test_struct_ref1, test_struct_clone, "the ref should deref to the same value as the item being stored"); assert_eq!(*test_struct_ref2, test_struct_clone, "the ref should deref to the same value as the item being stored"); Ok(()) } #[test] fn lock_borrow_interaction() -> Result<(), Box> { let store = Store::new(); let test_struct_a_1 = TestStructA { prop_1: 1, prop_2: "".into() }; let test_struct_a_2 = test_struct_a_1.clone(); let test_struct_b = TestStructB { prop_1: 1, prop_2: "".into(), prop_3: true }; let key_1 = 5; let key_2 = 10; store.store(key_1, test_struct_a_1)?; store.store(key_2, test_struct_a_2)?; store.store(key_1, test_struct_b)?; let test_struct_a_1_ref = store.borrow::<_, TestStructA>(key_1).expect("should be able to borrow an item when it's not locked"); assert_eq!( mem::discriminant(&store.lock::<_, TestStructA>(key_1).err().expect("should error")), mem::discriminant(&LockError::Borrowed), "error type should be Borrowed when trying to lock a borrowed item" ); store.lock::<_, TestStructA>(key_2).expect("should be able to lock an item with the same type but a different key"); store.lock::<_, TestStructB>(key_1).expect("should be able to lock an item with the same key but a different type"); drop(test_struct_a_1_ref); let test_struct_a_1_lock = store.lock::<_, TestStructA>(key_1).expect("should be able to lock an item when it's not borrowed"); assert_eq!( mem::discriminant(&store.borrow::<_, TestStructA>(key_1).err().expect("should error")), mem::discriminant(&BorrowError::Locked), "error type should be Borrowed when trying to borrow a locked item" ); store.borrow::<_, TestStructA>(key_2).expect("should be able to borrow an item with the same type but a different key"); store.borrow::<_, TestStructB>(key_1).expect("should be able to borrow an item with the same key but a different type"); drop(test_struct_a_1_lock); Ok(()) }