1#![deny(
6 missing_docs,
7 non_camel_case_types,
8 non_snake_case,
9 path_statements,
10 trivial_casts,
11 trivial_numeric_casts,
12 unsafe_code,
13 unstable_features,
14 unused_allocation,
15 unused_import_braces,
16 unused_imports,
17 unused_must_use,
18 unused_mut,
19 while_true,
20 clippy::panic,
21 clippy::print_stdout,
22 clippy::todo,
23 clippy::wrong_pub_self_convention
25)]
26#![warn(clippy::pedantic)]
27#![allow(clippy::missing_errors_doc, clippy::module_name_repetitions)]
29
30pub mod backend;
198pub mod deser;
200pub mod error;
202
203pub use crate::deser::DeSerializer;
205use std::fmt::Debug;
206use std::ops::Deref;
207use std::path::PathBuf;
208use std::sync::{Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard};
209
210use serde::de::DeserializeOwned;
211use serde::Serialize;
212
213#[cfg(feature = "mmap")]
214use crate::backend::MmapStorage;
215use crate::backend::{Backend, FileBackend, MemoryBackend, PathBackend};
216
217pub use crate::error::*;
218
219#[derive(Debug)]
235pub struct Database<Data, Back, DeSer> {
236 data: RwLock<Data>,
237 backend: Mutex<Back>,
238 deser: DeSer,
239}
240
241impl<Data, Back, DeSer> Database<Data, Back, DeSer>
242where
243 Data: Serialize + DeserializeOwned + Clone + Send,
244 Back: Backend,
245 DeSer: DeSerializer<Data> + Send + Sync + Clone,
246{
247 pub fn write<T, R>(&self, task: T) -> error::Result<R>
297 where
298 T: FnOnce(&mut Data) -> R,
299 {
300 let mut lock = self.data.write().map_err(|_| Error::Poison)?;
301 Ok(task(&mut lock))
302 }
303
304 pub fn write_safe<T>(&self, task: T) -> error::Result<()>
379 where
380 T: FnOnce(&mut Data) + std::panic::UnwindSafe,
381 {
382 let mut lock = self.data.write().map_err(|_| Error::Poison)?;
383 let mut data = lock.clone();
384 std::panic::catch_unwind(::std::panic::AssertUnwindSafe(|| {
385 task(&mut data);
386 }))
387 .map_err(|_| Error::WritePanic)?;
388 *lock = data;
389 Ok(())
390 }
391
392 pub fn read<T, R>(&self, task: T) -> error::Result<R>
410 where
411 T: FnOnce(&Data) -> R,
412 {
413 let mut lock = self.data.read().map_err(|_| Error::Poison)?;
414 Ok(task(&mut lock))
415 }
416
417 pub fn borrow_data<'a>(&'a self) -> error::Result<RwLockReadGuard<'a, Data>> {
454 self.data.read().map_err(|_| Error::Poison)
455 }
456
457 pub fn borrow_data_mut<'a>(&'a self) -> error::Result<RwLockWriteGuard<'a, Data>> {
506 self.data.write().map_err(|_| Error::Poison)
507 }
508
509 fn load_from_backend(backend: &mut Back, deser: &DeSer) -> error::Result<Data> {
511 let new_data = deser.deserialize(&backend.get_data()?[..])?;
512
513 Ok(new_data)
514 }
515
516 fn load_get_data_lock(&self) -> error::Result<RwLockWriteGuard<'_, Data>> {
518 let mut backend_lock = self.backend.lock().map_err(|_| Error::Poison)?;
519
520 let fresh_data = Self::load_from_backend(&mut backend_lock, &self.deser)?;
521 drop(backend_lock);
522
523 let mut data_write_lock = self.data.write().map_err(|_| Error::Poison)?;
524 *data_write_lock = fresh_data;
525 Ok(data_write_lock)
526 }
527
528 pub fn load(&self) -> error::Result<()> {
530 self.load_get_data_lock().map(|_| ())
531 }
532
533 fn save_data_locked<L: Deref<Target = Data>>(&self, lock: L) -> error::Result<()> {
535 let ser = self.deser.serialize(lock.deref())?;
536 drop(lock);
537
538 let mut backend = self.backend.lock().map_err(|_| Error::Poison)?;
539 backend.put_data(&ser)?;
540 Ok(())
541 }
542
543 pub fn save(&self) -> error::Result<()> {
545 let data = self.data.read().map_err(|_| Error::Poison)?;
546 self.save_data_locked(data)
547 }
548
549 pub fn get_data(&self, load: bool) -> error::Result<Data> {
554 let data = if load {
555 self.load_get_data_lock()?
556 } else {
557 self.data.write().map_err(|_| Error::Poison)?
558 };
559 Ok(data.clone())
560 }
561
562 pub fn put_data(&self, new_data: Data, save: bool) -> error::Result<()> {
566 let mut data = self.data.write().map_err(|_| Error::Poison)?;
567 *data = new_data;
568 if save {
569 self.save_data_locked(data)
570 } else {
571 Ok(())
572 }
573 }
574
575 pub fn from_parts(data: Data, backend: Back, deser: DeSer) -> Self {
577 Self {
578 data: RwLock::new(data),
579 backend: Mutex::new(backend),
580 deser,
581 }
582 }
583
584 pub fn into_inner(self) -> error::Result<(Data, Back, DeSer)> {
586 Ok((
587 self.data.into_inner().map_err(|_| Error::Poison)?,
588 self.backend
589 .into_inner()
590 .map_err(|_| Error::Poison)?,
591 self.deser,
592 ))
593 }
594
595 pub fn try_clone(&self) -> error::Result<MemoryDatabase<Data, DeSer>> {
638 let lock = self.data.read().map_err(|_| Error::Poison)?;
639
640 Ok(Database {
641 data: RwLock::new(lock.clone()),
642 backend: Mutex::new(MemoryBackend::new()),
643 deser: self.deser.clone(),
644 })
645 }
646}
647
648pub type FileDatabase<D, DS> = Database<D, FileBackend, DS>;
650
651impl<Data, DeSer> Database<Data, FileBackend, DeSer>
652where
653 Data: Serialize + DeserializeOwned + Clone + Send,
654 DeSer: DeSerializer<Data> + Send + Sync + Clone,
655{
656 pub fn load_from_path<S>(path: S) -> error::Result<Self>
659 where
660 S: AsRef<std::path::Path>,
661 {
662 let mut backend = FileBackend::from_path_or_fail(path)?;
663 let deser = DeSer::default();
664 let data = Self::load_from_backend(&mut backend, &deser)?;
665
666 let db = Self {
667 data: RwLock::new(data),
668 backend: Mutex::new(backend),
669 deser,
670 };
671 Ok(db)
672 }
673
674 pub fn load_from_path_or<S>(path: S, data: Data) -> error::Result<Self>
680 where
681 S: AsRef<std::path::Path>,
682 {
683 let (mut backend, exists) = FileBackend::from_path_or_create(path)?;
684 let deser = DeSer::default();
685 if !exists {
686 let ser = deser.serialize(&data)?;
687 backend.put_data(&ser)?;
688 }
689
690 let db = Self {
691 data: RwLock::new(data),
692 backend: Mutex::new(backend),
693 deser,
694 };
695
696 if exists {
697 db.load()?;
698 }
699
700 Ok(db)
701 }
702
703 pub fn load_from_path_or_else<S, C>(path: S, closure: C) -> error::Result<Self>
709 where
710 S: AsRef<std::path::Path>,
711 C: FnOnce() -> Data,
712 {
713 let (mut backend, exists) = FileBackend::from_path_or_create(path)?;
714 let deser = DeSer::default();
715 let data = if exists {
716 Self::load_from_backend(&mut backend, &deser)?
717 } else {
718 let data = closure();
719
720 let ser = deser.serialize(&data)?;
721 backend.put_data(&ser)?;
722
723 data
724 };
725
726 let db = Self {
727 data: RwLock::new(data),
728 backend: Mutex::new(backend),
729 deser,
730 };
731 Ok(db)
732 }
733
734 pub fn create_at_path<S>(path: S, data: Data) -> error::Result<Self>
741 where
742 S: AsRef<std::path::Path>,
743 {
744 let (mut backend, exists) = FileBackend::from_path_or_create(path)?;
745 let deser = DeSer::default();
746 if !exists {
747 let ser = deser.serialize(&data)?;
748 backend.put_data(&ser)?;
749 }
750
751 let db = Self {
752 data: RwLock::new(data),
753 backend: Mutex::new(backend),
754 deser,
755 };
756 Ok(db)
757 }
758
759 pub fn from_file(file: std::fs::File, data: Data) -> error::Result<Self> {
761 let backend = FileBackend::from_file(file);
762
763 Ok(Self {
764 data: RwLock::new(data),
765 backend: Mutex::new(backend),
766 deser: DeSer::default(),
767 })
768 }
769}
770
771impl<Data, DeSer> Database<Data, FileBackend, DeSer>
772where
773 Data: Serialize + DeserializeOwned + Clone + Send + Default,
774 DeSer: DeSerializer<Data> + Send + Sync + Clone,
775{
776 pub fn load_from_path_or_default<S>(path: S) -> error::Result<Self>
782 where
783 S: AsRef<std::path::Path>,
784 {
785 Self::load_from_path_or_else(path, Data::default)
786 }
787}
788
789pub type PathDatabase<D, DS> = Database<D, PathBackend, DS>;
791
792impl<Data, DeSer> Database<Data, PathBackend, DeSer>
793where
794 Data: Serialize + DeserializeOwned + Clone + Send,
795 DeSer: DeSerializer<Data> + Send + Sync + Clone,
796{
797 pub fn load_from_path(path: PathBuf) -> error::Result<Self> {
800 let mut backend = PathBackend::from_path_or_fail(path)?;
801 let deser = DeSer::default();
802 let data = Self::load_from_backend(&mut backend, &deser)?;
803
804 let db = Self {
805 data: RwLock::new(data),
806 backend: Mutex::new(backend),
807 deser,
808 };
809 Ok(db)
810 }
811
812 pub fn load_from_path_or(path: PathBuf, data: Data) -> error::Result<Self> {
818 let (mut backend, exists) = PathBackend::from_path_or_create(path)?;
819 let deser = DeSer::default();
820 if !exists {
821 let ser = deser.serialize(&data)?;
822 backend.put_data(&ser)?;
823 }
824
825 let db = Self {
826 data: RwLock::new(data),
827 backend: Mutex::new(backend),
828 deser,
829 };
830
831 if exists {
832 db.load()?;
833 }
834
835 Ok(db)
836 }
837
838 pub fn load_from_path_or_else<C>(path: PathBuf, closure: C) -> error::Result<Self>
844 where
845 C: FnOnce() -> Data,
846 {
847 let (mut backend, exists) = PathBackend::from_path_or_create(path)?;
848 let deser = DeSer::default();
849 let data = if exists {
850 Self::load_from_backend(&mut backend, &deser)?
851 } else {
852 let data = closure();
853
854 let ser = deser.serialize(&data)?;
855 backend.put_data(&ser)?;
856
857 data
858 };
859
860 let db = Self {
861 data: RwLock::new(data),
862 backend: Mutex::new(backend),
863 deser,
864 };
865 Ok(db)
866 }
867
868 pub fn create_at_path(path: PathBuf, data: Data) -> error::Result<Self> {
875 let (mut backend, exists) = PathBackend::from_path_or_create(path)?;
876 let deser = DeSer::default();
877 if !exists {
878 let ser = deser.serialize(&data)?;
879 backend.put_data(&ser)?;
880 }
881
882 let db = Self {
883 data: RwLock::new(data),
884 backend: Mutex::new(backend),
885 deser,
886 };
887 Ok(db)
888 }
889}
890
891impl<Data, DeSer> Database<Data, PathBackend, DeSer>
892where
893 Data: Serialize + DeserializeOwned + Clone + Send + Default,
894 DeSer: DeSerializer<Data> + Send + Sync + Clone,
895{
896 pub fn load_from_path_or_default(path: PathBuf) -> error::Result<Self> {
902 Self::load_from_path_or_else(path, Data::default)
903 }
904}
905
906pub type MemoryDatabase<D, DS> = Database<D, MemoryBackend, DS>;
908
909impl<Data, DeSer> Database<Data, MemoryBackend, DeSer>
910where
911 Data: Serialize + DeserializeOwned + Clone + Send,
912 DeSer: DeSerializer<Data> + Send + Sync + Clone,
913{
914 pub fn memory(data: Data) -> error::Result<Self> {
916 let backend = MemoryBackend::new();
917
918 Ok(Self {
919 data: RwLock::new(data),
920 backend: Mutex::new(backend),
921 deser: DeSer::default(),
922 })
923 }
924}
925
926#[cfg(feature = "mmap")]
928pub type MmapDatabase<D, DS> = Database<D, MmapStorage, DS>;
929
930#[cfg(feature = "mmap")]
931impl<Data, DeSer> Database<Data, MmapStorage, DeSer>
932where
933 Data: Serialize + DeserializeOwned + Clone + Send,
934 DeSer: DeSerializer<Data> + Send + Sync + Clone,
935{
936 pub fn mmap(data: Data) -> error::Result<Self> {
938 let backend = MmapStorage::new()?;
939
940 Ok(Self {
941 data: RwLock::new(data),
942 backend: Mutex::new(backend),
943 deser: DeSer::default(),
944 })
945 }
946
947 pub fn mmap_with_size(data: Data, size: usize) -> error::Result<Self> {
949 let backend = MmapStorage::with_size(size)?;
950
951 Ok(Self {
952 data: RwLock::new(data),
953 backend: Mutex::new(backend),
954 deser: DeSer::default(),
955 })
956 }
957}
958
959impl<Data, Back, DeSer> Database<Data, Back, DeSer> {
960 pub fn with_deser<T>(self, deser: T) -> Database<Data, Back, T> {
962 Database {
963 backend: self.backend,
964 data: self.data,
965 deser,
966 }
967 }
968}
969
970impl<Data, Back, DeSer> Database<Data, Back, DeSer> {
971 pub fn with_backend<T>(self, backend: T) -> Database<Data, T, DeSer> {
976 Database {
977 backend: Mutex::new(backend),
978 data: self.data,
979 deser: self.deser,
980 }
981 }
982}
983
984impl<Data, Back, DeSer> Database<Data, Back, DeSer>
985where
986 Data: Serialize + DeserializeOwned + Clone + Send,
987 Back: Backend,
988 DeSer: DeSerializer<Data> + Send + Sync + Clone,
989{
990 pub fn convert_data<C, OutputData>(
994 self,
995 convert: C,
996 ) -> error::Result<Database<OutputData, Back, DeSer>>
997 where
998 OutputData: Serialize + DeserializeOwned + Clone + Send,
999 C: FnOnce(Data) -> OutputData,
1000 DeSer: DeSerializer<OutputData> + Send + Sync,
1001 {
1002 let (data, backend, deser) = self.into_inner()?;
1003 Ok(Database {
1004 data: RwLock::new(convert(data)),
1005 backend: Mutex::new(backend),
1006 deser,
1007 })
1008 }
1009}
1010
1011#[cfg(test)]
1012mod tests {
1013 use super::*;
1014 use std::collections::HashMap;
1015 use tempfile::NamedTempFile;
1016
1017 type TestData = HashMap<usize, String>;
1018 type TestDb<B> = Database<TestData, B, crate::deser::Ron>;
1019 type TestMemDb = TestDb<MemoryBackend>;
1020
1021 fn test_data() -> TestData {
1022 let mut data = HashMap::new();
1023 data.insert(1, "Hello World".to_string());
1024 data.insert(100, "Rustbreak".to_string());
1025 data
1026 }
1027
1028 #[derive(Clone, Debug, Serialize, serde::Deserialize)]
1030 struct PanicDefault;
1031 impl Default for PanicDefault {
1032 fn default() -> Self {
1033 panic!("`default` was called but should not")
1034 }
1035 }
1036
1037 #[test]
1038 fn create_db_and_read() {
1039 let db = TestMemDb::memory(test_data()).expect("Could not create database");
1040 assert_eq!(
1041 "Hello World",
1042 db.read(|d| d.get(&1).cloned())
1043 .expect("Rustbreak read error")
1044 .expect("Should be `Some` but was `None`")
1045 );
1046 assert_eq!(
1047 "Rustbreak",
1048 db.read(|d| d.get(&100).cloned())
1049 .expect("Rustbreak read error")
1050 .expect("Should be `Some` but was `None`")
1051 );
1052 }
1053
1054 #[test]
1055 fn write_twice() {
1056 let db = TestMemDb::memory(test_data()).expect("Could not create database");
1057 db.write(|d| d.insert(3, "Write to db".to_string()))
1058 .expect("Rustbreak write error");
1059 db.write(|d| d.insert(3, "Second write".to_string()))
1060 .expect("Rustbreak write error");
1061 assert_eq!(
1062 "Hello World",
1063 db.read(|d| d.get(&1).cloned())
1064 .expect("Rustbreak read error")
1065 .expect("Should be `Some` but was `None`")
1066 );
1067 assert_eq!(
1068 "Rustbreak",
1069 db.read(|d| d.get(&100).cloned())
1070 .expect("Rustbreak read error")
1071 .expect("Should be `Some` but was `None`")
1072 );
1073 assert_eq!(
1074 "Second write",
1075 db.read(|d| d.get(&3).cloned())
1076 .expect("Rustbreak read error")
1077 .expect("Should be `Some` but was `None`")
1078 );
1079 }
1080
1081 #[test]
1082 fn save_load() {
1083 let db = TestMemDb::memory(test_data()).expect("Could not create database");
1084 db.save().expect("Rustbreak save error");
1085 db.write(|d| d.clear()).expect("Rustbreak write error");
1086 db.load().expect("Rustbreak load error");
1087 assert_eq!(
1088 "Hello World",
1089 db.read(|d| d.get(&1).cloned())
1090 .expect("Rustbreak read error")
1091 .expect("Should be `Some` but was `None`")
1092 );
1093 assert_eq!(
1094 "Rustbreak",
1095 db.read(|d| d.get(&100).cloned())
1096 .expect("Rustbreak read error")
1097 .expect("Should be `Some` but was `None`")
1098 );
1099 }
1100
1101 #[test]
1102 fn writesafe_twice() {
1103 let db = TestMemDb::memory(test_data()).expect("Could not create database");
1104 db.write_safe(|d| {
1105 d.insert(3, "Write to db".to_string());
1106 })
1107 .expect("Rustbreak write error");
1108 db.write_safe(|d| {
1109 d.insert(3, "Second write".to_string());
1110 })
1111 .expect("Rustbreak write error");
1112 assert_eq!(
1113 "Hello World",
1114 db.read(|d| d.get(&1).cloned())
1115 .expect("Rustbreak read error")
1116 .expect("Should be `Some` but was `None`")
1117 );
1118 assert_eq!(
1119 "Rustbreak",
1120 db.read(|d| d.get(&100).cloned())
1121 .expect("Rustbreak read error")
1122 .expect("Should be `Some` but was `None`")
1123 );
1124 assert_eq!(
1125 "Second write",
1126 db.read(|d| d.get(&3).cloned())
1127 .expect("Rustbreak read error")
1128 .expect("Should be `Some` but was `None`")
1129 );
1130 }
1131
1132 #[test]
1133 fn writesafe_panic() {
1134 let db = TestMemDb::memory(test_data()).expect("Could not create database");
1135 let err = db
1136 .write_safe(|d| {
1137 d.clear();
1138 panic!("Panic should be catched")
1139 })
1140 .expect_err("Did not error on panic in safe write!");
1141 assert!(matches!(err, Error::WritePanic));
1142
1143 assert_eq!(
1144 "Hello World",
1145 db.read(|d| d.get(&1).cloned())
1146 .expect("Rustbreak read error")
1147 .expect("Should be `Some` but was `None`")
1148 );
1149 assert_eq!(
1150 "Rustbreak",
1151 db.read(|d| d.get(&100).cloned())
1152 .expect("Rustbreak read error")
1153 .expect("Should be `Some` but was `None`")
1154 );
1155 }
1156
1157 #[test]
1158 fn borrow_data_twice() {
1159 let db = TestMemDb::memory(test_data()).expect("Could not create database");
1160 let readlock1 = db.borrow_data().expect("Rustbreak readlock error");
1161 let readlock2 = db.borrow_data().expect("Rustbreak readlock error");
1162 assert_eq!(
1163 "Hello World",
1164 readlock1.get(&1).expect("Should be `Some` but was `None`")
1165 );
1166 assert_eq!(
1167 "Hello World",
1168 readlock2.get(&1).expect("Should be `Some` but was `None`")
1169 );
1170 assert_eq!(
1171 "Rustbreak",
1172 readlock1
1173 .get(&100)
1174 .expect("Should be `Some` but was `None`")
1175 );
1176 assert_eq!(
1177 "Rustbreak",
1178 readlock2
1179 .get(&100)
1180 .expect("Should be `Some` but was `None`")
1181 );
1182 assert_eq!(*readlock1, *readlock2);
1183 }
1184
1185 #[test]
1186 fn borrow_data_mut() {
1187 let db = TestMemDb::memory(test_data()).expect("Could not create database");
1188 let mut writelock = db.borrow_data_mut().expect("Rustbreak writelock error");
1189 writelock.insert(3, "Write to db".to_string());
1190 drop(writelock);
1191 assert_eq!(
1192 "Hello World",
1193 db.read(|d| d.get(&1).cloned())
1194 .expect("Rustbreak read error")
1195 .expect("Should be `Some` but was `None`")
1196 );
1197 assert_eq!(
1198 "Rustbreak",
1199 db.read(|d| d.get(&100).cloned())
1200 .expect("Rustbreak read error")
1201 .expect("Should be `Some` but was `None`")
1202 );
1203 assert_eq!(
1204 "Write to db",
1205 db.read(|d| d.get(&3).cloned())
1206 .expect("Rustbreak read error")
1207 .expect("Should be `Some` but was `None`")
1208 );
1209 }
1210
1211 #[test]
1212 fn get_data_mem() {
1213 let db = TestMemDb::memory(test_data()).expect("Could not create database");
1214 let data = db.get_data(false).expect("could not get data");
1215 assert_eq!(test_data(), data);
1216 }
1217
1218 #[test]
1219 fn get_data_load() {
1220 let db = TestMemDb::memory(test_data()).expect("Could not create database");
1221 db.save().expect("Rustbreak save error");
1222 db.write(|d| d.clear()).expect("Rustbreak write error");
1223 let data = db.get_data(true).expect("could not get data");
1224 assert_eq!(test_data(), data);
1225 }
1226
1227 #[test]
1228 fn put_data_mem() {
1229 let db = TestMemDb::memory(TestData::default()).expect("Could not create database");
1230 db.put_data(test_data(), false).expect("could not put data");
1231 assert_eq!(
1232 "Hello World",
1233 db.read(|d| d.get(&1).cloned())
1234 .expect("Rustbreak read error")
1235 .expect("Should be `Some` but was `None`")
1236 );
1237 assert_eq!(
1238 "Rustbreak",
1239 db.read(|d| d.get(&100).cloned())
1240 .expect("Rustbreak read error")
1241 .expect("Should be `Some` but was `None`")
1242 );
1243 let data = db.get_data(false).expect("could not get data");
1244 assert_eq!(test_data(), data);
1245 }
1246
1247 #[test]
1248 fn put_data_save() {
1249 let db = TestMemDb::memory(TestData::default()).expect("Could not create database");
1250 db.put_data(test_data(), true).expect("could not put data");
1251 db.load().expect("Rustbreak load error");
1252 assert_eq!(
1253 "Hello World",
1254 db.read(|d| d.get(&1).cloned())
1255 .expect("Rustbreak read error")
1256 .expect("Should be `Some` but was `None`")
1257 );
1258 assert_eq!(
1259 "Rustbreak",
1260 db.read(|d| d.get(&100).cloned())
1261 .expect("Rustbreak read error")
1262 .expect("Should be `Some` but was `None`")
1263 );
1264 let data = db.get_data(false).expect("could not get data");
1265 assert_eq!(test_data(), data);
1266 }
1267
1268 #[test]
1269 fn save_and_into_inner() {
1270 let db = TestMemDb::memory(test_data()).expect("Could not create database");
1271 db.save().expect("Rustbreak save error");
1272 let (data, mut backend, _) = db
1273 .into_inner()
1274 .expect("error calling `Database.into_inner`");
1275 assert_eq!(test_data(), data);
1276 let parsed: TestData =
1277 ron::de::from_reader(&backend.get_data().expect("could not get data from backend")[..])
1278 .expect("backend contains invalid RON");
1279 assert_eq!(test_data(), parsed);
1280 }
1281
1282 #[test]
1283 fn clone() {
1284 let db1 = TestMemDb::memory(test_data()).expect("Could not create database");
1285 let readlock1 = db1.borrow_data().expect("Rustbreak readlock error");
1286 let db2 = db1.try_clone().expect("Rustbreak clone error");
1287 let readlock2 = db2.borrow_data().expect("Rustbreak readlock error");
1288 assert_eq!(test_data(), *readlock1);
1289 assert_eq!(*readlock1, *readlock2);
1290 }
1291
1292 #[test]
1293 fn allow_databases_with_boxed_backend() {
1294 let db =
1295 MemoryDatabase::<Vec<u64>, crate::deser::Ron>::memory(vec![]).expect("To be created");
1296 let db: Database<_, Box<dyn Backend>, _> = db.with_backend(Box::new(MemoryBackend::new()));
1297 db.put_data(vec![1, 2, 3], true)
1298 .expect("Can save data in memory");
1299 assert_eq!(
1300 &[1, 2, 3],
1301 &db.get_data(true).expect("Can get data from memory")[..]
1302 );
1303 }
1304
1305 #[test]
1308 fn save_holding_readlock() {
1309 let db = TestMemDb::memory(test_data()).expect("Could not create database");
1310 let readlock = db.borrow_data().expect("Rustbreak readlock error");
1311 db.save().expect("Rustbreak save error");
1312 assert_eq!(test_data(), *readlock);
1313 }
1314
1315 #[test]
1317 #[cfg_attr(miri, ignore)]
1318 fn pathdb_from_path_or_else_existing_nocall() {
1319 let file = NamedTempFile::new().expect("could not create temporary file");
1320 let path = file.path().to_owned();
1321 let _ = TestDb::<PathBackend>::load_from_path_or_else(path, || {
1322 panic!("closure called while file existed")
1323 });
1324 }
1325
1326 #[test]
1328 #[cfg_attr(miri, ignore)]
1329 fn filedb_from_path_or_else_existing_nocall() {
1330 let file = NamedTempFile::new().expect("could not create temporary file");
1331 let path = file.path();
1332 let _ = TestDb::<FileBackend>::load_from_path_or_else(path, || {
1333 panic!("closure called while file existed")
1334 });
1335 }
1336
1337 #[test]
1339 #[cfg_attr(miri, ignore)]
1340 fn pathdb_from_path_or_default_existing_nocall() {
1341 let file = NamedTempFile::new().expect("could not create temporary file");
1342 let path = file.path().to_owned();
1343 let _ = Database::<PanicDefault, PathBackend, crate::deser::Ron>::load_from_path_or_default(
1344 path,
1345 );
1346 }
1347
1348 #[test]
1350 #[cfg_attr(miri, ignore)]
1351 fn filedb_from_path_or_default_existing_nocall() {
1352 let file = NamedTempFile::new().expect("could not create temporary file");
1353 let path = file.path();
1354 let _ = Database::<PanicDefault, FileBackend, crate::deser::Ron>::load_from_path_or_default(
1355 path,
1356 );
1357 }
1358
1359 #[test]
1360 #[cfg_attr(miri, ignore)]
1361 fn pathdb_from_path_or_new() {
1362 let dir = tempfile::tempdir().expect("could not create temporary directory");
1363 let mut file_path = dir.path().to_owned();
1364 file_path.push("rustbreak_path_db.db");
1365 let db = TestDb::<PathBackend>::load_from_path_or(file_path, test_data())
1366 .expect("could not load from path");
1367 db.load().expect("could not load");
1368 let readlock = db.borrow_data().expect("Rustbreak readlock error");
1369 assert_eq!(test_data(), *readlock);
1370 dir.close().expect("Error while deleting temp directory!");
1371 }
1372
1373 #[test]
1374 #[cfg_attr(miri, ignore)]
1375 fn pathdb_from_path_or_else_new() {
1376 let dir = tempfile::tempdir().expect("could not create temporary directory");
1377 let mut file_path = dir.path().to_owned();
1378 file_path.push("rustbreak_path_db.db");
1379 let db = TestDb::<PathBackend>::load_from_path_or_else(file_path, test_data)
1380 .expect("could not load from path");
1381 db.load().expect("could not load");
1382 let readlock = db.borrow_data().expect("Rustbreak readlock error");
1383 assert_eq!(test_data(), *readlock);
1384 dir.close().expect("Error while deleting temp directory!");
1385 }
1386
1387 #[test]
1388 #[cfg_attr(miri, ignore)]
1389 fn filedb_from_path_or_new() {
1390 let dir = tempfile::tempdir().expect("could not create temporary directory");
1391 let mut file_path = dir.path().to_owned();
1392 file_path.push("rustbreak_path_db.db");
1393 let db = TestDb::<FileBackend>::load_from_path_or(file_path, test_data())
1394 .expect("could not load from path");
1395 db.load().expect("could not load");
1396 let readlock = db.borrow_data().expect("Rustbreak readlock error");
1397 assert_eq!(test_data(), *readlock);
1398 dir.close().expect("Error while deleting temp directory!");
1399 }
1400
1401 #[test]
1402 #[cfg_attr(miri, ignore)]
1403 fn filedb_from_path_or_else_new() {
1404 let dir = tempfile::tempdir().expect("could not create temporary directory");
1405 let mut file_path = dir.path().to_owned();
1406 file_path.push("rustbreak_path_db.db");
1407 let db = TestDb::<FileBackend>::load_from_path_or_else(file_path, test_data)
1408 .expect("could not load from path");
1409 db.load().expect("could not load");
1410 let readlock = db.borrow_data().expect("Rustbreak readlock error");
1411 assert_eq!(test_data(), *readlock);
1412 dir.close().expect("Error while deleting temp directory!");
1413 }
1414
1415 #[test]
1416 #[cfg_attr(miri, ignore)]
1417 fn pathdb_from_path_new_fail() {
1418 let dir = tempfile::tempdir().expect("could not create temporary directory");
1419 let mut file_path = dir.path().to_owned();
1420 file_path.push("rustbreak_path_db.db");
1421 let err = TestDb::<PathBackend>::load_from_path(file_path)
1422 .expect_err("should fail with file not found");
1423 if let Error::Backend(BackendError::Io(io_err)) = &err {
1424 assert_eq!(std::io::ErrorKind::NotFound, io_err.kind());
1425 } else {
1426 panic!("Wrong error: {}", err)
1427 };
1428
1429 dir.close().expect("Error while deleting temp directory!");
1430 }
1431
1432 #[test]
1433 #[cfg_attr(miri, ignore)]
1434 fn filedb_from_path_new_fail() {
1435 let dir = tempfile::tempdir().expect("could not create temporary directory");
1436 let mut file_path = dir.path().to_owned();
1437 file_path.push("rustbreak_path_db.db");
1438 let err = TestDb::<FileBackend>::load_from_path(file_path)
1439 .expect_err("should fail with file not found");
1440 if let Error::Backend(BackendError::Io(io_err)) = &err {
1441 assert_eq!(std::io::ErrorKind::NotFound, io_err.kind());
1442 } else {
1443 panic!("Wrong error: {}", err)
1444 };
1445
1446 dir.close().expect("Error while deleting temp directory!");
1447 }
1448
1449 #[test]
1450 #[cfg_attr(miri, ignore)]
1451 fn pathdb_from_path_existing() {
1452 let file = NamedTempFile::new().expect("could not create temporary file");
1453 let path = file.path().to_owned();
1454 let db = TestDb::<PathBackend>::create_at_path(path.clone(), test_data())
1456 .expect("could not create db");
1457 db.save().expect("could not save db");
1458 drop(db);
1459 let db = TestDb::<PathBackend>::load_from_path(path).expect("could not load");
1461 let readlock = db.borrow_data().expect("Rustbreak readlock error");
1462 assert_eq!(test_data(), *readlock);
1463 }
1464
1465 #[test]
1466 #[cfg_attr(miri, ignore)]
1467 fn filedb_from_path_existing() {
1468 let file = NamedTempFile::new().expect("could not create temporary file");
1469 let path = file.path();
1470 let db =
1472 TestDb::<FileBackend>::create_at_path(path, test_data()).expect("could not create db");
1473 db.save().expect("could not save db");
1474 drop(db);
1475 let db = TestDb::<FileBackend>::load_from_path(path).expect("could not load");
1477 let readlock = db.borrow_data().expect("Rustbreak readlock error");
1478 assert_eq!(test_data(), *readlock);
1479 }
1480}