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