bevy_persistent/
builder.rs1use crate::prelude::*;
4
5pub struct PersistentBuilder<R: Resource + Serialize + DeserializeOwned> {
7 pub(crate) name: Option<String>,
8 pub(crate) format: Option<StorageFormat>,
9 pub(crate) path: Option<PathBuf>,
10 pub(crate) loaded: bool,
11 pub(crate) default: Option<R>,
12 pub(crate) revertible: bool,
13 pub(crate) revert_to_default_on_deserialization_errors: bool,
14}
15
16impl<R: Resource + Serialize + DeserializeOwned> PersistentBuilder<R> {
17 pub fn name(mut self, name: impl ToString) -> PersistentBuilder<R> {
19 self.name = Some(name.to_string());
20 self
21 }
22
23 pub fn format(mut self, format: StorageFormat) -> PersistentBuilder<R> {
25 self.format = Some(format);
26 self
27 }
28
29 pub fn path(mut self, path: impl Into<PathBuf>) -> PersistentBuilder<R> {
31 self.path = Some(path.into());
32 self
33 }
34
35 pub fn loaded(mut self, loaded: bool) -> PersistentBuilder<R> {
37 self.loaded = loaded;
38 self
39 }
40
41 pub fn unloaded(mut self, unloaded: bool) -> PersistentBuilder<R> {
43 self.loaded = !unloaded;
44 self
45 }
46
47 pub fn default(mut self, resource: R) -> PersistentBuilder<R> {
49 self.default = Some(resource);
50 self
51 }
52
53 pub fn revertible(mut self, revertible: bool) -> PersistentBuilder<R> {
55 self.revertible = revertible;
56 self
57 }
58
59 pub fn revert_to_default_on_deserialization_errors(
61 mut self,
62 revert_to_default_on_deserialization_errors: bool,
63 ) -> PersistentBuilder<R> {
64 self.revert_to_default_on_deserialization_errors =
65 revert_to_default_on_deserialization_errors;
66 self
67 }
68}
69
70impl<R: Resource + Serialize + DeserializeOwned> PersistentBuilder<R> {
71 #[cfg(any(
77 feature = "bincode",
78 feature = "ini",
79 feature = "json",
80 feature = "ron",
81 feature = "toml",
82 feature = "yaml",
83 ))]
84 pub fn build(self) -> Result<Persistent<R>, PersistenceError> {
85 if self.name.is_none() {
86 panic!("persistent resource name is not set");
87 }
88 if self.format.is_none() {
89 panic!("persistent resource format is not set");
90 }
91 if self.path.is_none() {
92 panic!("persistent resource path is not set");
93 }
94 if self.default.is_none() {
95 panic!("persistent resource default is not set");
96 }
97
98 let name = self.name.unwrap();
99 let format = self.format.unwrap();
100 let path = self.path.unwrap();
101 let loaded = self.loaded;
102 let default = self.default.unwrap();
103 let revertible = self.revertible;
104 let revert_to_default_on_deserialization_errors =
105 self.revert_to_default_on_deserialization_errors;
106
107 let storage = {
108 #[cfg(not(target_family = "wasm"))]
109 {
110 Storage::Filesystem { path: path.canonicalize().unwrap_or(path) }
111 }
112 #[cfg(target_family = "wasm")]
113 {
114 let separator = std::path::MAIN_SEPARATOR_STR;
115 let path = path.strip_prefix(separator).unwrap_or(&path);
116
117 if let Ok(Some(key)) = path.strip_prefix("local").map(|p| p.to_str()) {
118 Storage::LocalStorage { key: key.to_owned() }
119 } else if let Ok(Some(key)) = path.strip_prefix("session").map(|p| p.to_str()) {
120 Storage::SessionStorage { key: key.to_owned() }
121 } else {
122 panic!(
123 "persistent resource path should start with \
124 \"local\" or \"session\" and be UTF-8 encoded \
125 in WebAssembly but it's {path:?}",
126 );
127 }
128 }
129 };
130
131 Persistent::new(
132 name,
133 format,
134 storage,
135 loaded,
136 default,
137 revertible,
138 revert_to_default_on_deserialization_errors,
139 )
140 }
141
142 #[cfg(not(any(
143 feature = "bincode",
144 feature = "ini",
145 feature = "json",
146 feature = "ron",
147 feature = "toml",
148 feature = "yaml",
149 )))]
150 pub fn build(self) -> Result<Persistent<R>, PersistenceError> {
151 unreachable!()
152 }
153}