1use std::ops::{Deref, DerefMut};
5use std::path::PathBuf;
6use std::str::FromStr;
7
8use serde::{Deserialize, Serialize};
9use servo_base::generic_channel::{
10 self, GenericCallback, GenericReceiver, GenericSender, SendResult,
11};
12use servo_base::id::WebViewId;
13use servo_url::ImmutableOrigin;
14
15#[derive(Clone, Debug, Deserialize, Serialize)]
16pub struct ClientStorageThreadHandle {
17 sender: GenericSender<ClientStorageThreadMessage>,
18}
19
20impl ClientStorageThreadHandle {
21 pub fn new(sender: GenericSender<ClientStorageThreadMessage>) -> Self {
22 ClientStorageThreadHandle { sender }
23 }
24
25 pub fn obtain_a_storage_bottle_map(
26 &self,
27 storage_type: StorageType,
28 webview: WebViewId,
29 storage_identifier: StorageIdentifier,
30 origin: ImmutableOrigin,
31 ) -> GenericReceiver<Result<StorageProxyMap, String>> {
32 let (sender, receiver) = generic_channel::channel().unwrap();
33 let message = ClientStorageThreadMessage::ObtainBottleMap {
34 storage_type,
35 webview,
36 storage_identifier,
37 origin,
38 sender,
39 };
40 self.sender.send(message).unwrap();
41 receiver
42 }
43
44 pub fn create_database(
45 &self,
46 bottle_id: i64,
47 name: String,
48 ) -> GenericReceiver<Result<PathBuf, String>> {
49 let (sender, receiver) = generic_channel::channel().unwrap();
50 let message = ClientStorageThreadMessage::CreateDatabase {
51 bottle_id,
52 name,
53 sender,
54 };
55 self.sender.send(message).unwrap();
56 receiver
57 }
58
59 pub fn delete_database(
60 &self,
61 bottle_id: i64,
62 name: String,
63 ) -> GenericReceiver<Result<(), String>> {
64 let (sender, receiver) = generic_channel::channel().unwrap();
65 let message = ClientStorageThreadMessage::DeleteDatabase {
66 bottle_id,
67 name,
68 sender,
69 };
70 self.sender.send(message).unwrap();
71 receiver
72 }
73
74 pub fn persisted(
75 &self,
76 origin: ImmutableOrigin,
77 sender: GenericCallback<Result<bool, String>>,
78 ) -> SendResult {
79 self.sender
80 .send(ClientStorageThreadMessage::Persisted { origin, sender })
81 }
82
83 pub fn persist(
84 &self,
85 origin: ImmutableOrigin,
86 permission_granted: bool,
87 sender: GenericCallback<Result<bool, String>>,
88 ) -> SendResult {
89 self.sender.send(ClientStorageThreadMessage::Persist {
90 origin,
91 permission_granted,
92 sender,
93 })
94 }
95
96 pub fn estimate(
97 &self,
98 origin: ImmutableOrigin,
99 sender: GenericCallback<Result<(u64, u64), String>>,
100 ) -> SendResult {
101 self.sender
102 .send(ClientStorageThreadMessage::Estimate { origin, sender })
103 }
104}
105
106impl From<ClientStorageThreadHandle> for GenericSender<ClientStorageThreadMessage> {
107 fn from(handle: ClientStorageThreadHandle) -> Self {
108 handle.sender
109 }
110}
111
112impl Deref for ClientStorageThreadHandle {
113 type Target = GenericSender<ClientStorageThreadMessage>;
114
115 fn deref(&self) -> &Self::Target {
116 &self.sender
117 }
118}
119
120impl DerefMut for ClientStorageThreadHandle {
121 fn deref_mut(&mut self) -> &mut Self::Target {
122 &mut self.sender
123 }
124}
125
126#[derive(Debug, Deserialize, Serialize)]
128pub enum StorageType {
129 Local,
130 Session,
131}
132
133impl StorageType {
134 pub fn as_str(&self) -> &str {
135 match self {
136 StorageType::Local => "local",
137 StorageType::Session => "session",
138 }
139 }
140}
141
142#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
144pub enum Mode {
145 #[default]
147 BestEffort,
148 Persistent,
149}
150
151impl Mode {
152 pub fn as_str(&self) -> &str {
153 match self {
154 Mode::BestEffort => "best-effort",
155 Mode::Persistent => "persistent",
156 }
157 }
158}
159
160impl FromStr for Mode {
161 type Err = ();
162
163 fn from_str(value: &str) -> Result<Self, Self::Err> {
165 match value {
166 "best-effort" => Ok(Mode::BestEffort),
167 "persistent" => Ok(Mode::Persistent),
168 _ => Err(()),
169 }
170 }
171}
172
173#[derive(Debug, Deserialize, Serialize)]
175pub enum StorageIdentifier {
176 Caches,
177 IndexedDB,
178 LocalStorage,
179 ServiceWorkerRegistrations,
180 SessionStorage,
181}
182
183impl StorageIdentifier {
184 pub fn as_str(&self) -> &str {
185 match self {
186 StorageIdentifier::Caches => "caches",
187 StorageIdentifier::IndexedDB => "indexeddb",
188 StorageIdentifier::LocalStorage => "localstorage",
189 StorageIdentifier::ServiceWorkerRegistrations => "serviceworkerregistration",
190 StorageIdentifier::SessionStorage => "sessionstorage",
191 }
192 }
193}
194
195#[derive(Debug, Deserialize, Serialize)]
196pub enum CreateBucketError<T> {
197 BucketAlreadyExists,
198 Internal(T),
199}
200
201impl<T> From<T> for CreateBucketError<T> {
202 fn from(err: T) -> Self {
203 CreateBucketError::Internal(err)
204 }
205}
206
207#[derive(Debug, Deserialize, Serialize)]
208pub enum ClientStorageErrorr<T> {
209 BottleAlreadyExists,
210 BucketDoesNotExist,
211 DatabaseAlreadyExists,
212 DatabaseDoesNotExist,
213 DirectoryCreationFailed,
214 DirectoryDeletionFailed,
215 Internal(T),
216}
217
218impl<T> From<T> for ClientStorageErrorr<T> {
219 fn from(err: T) -> Self {
220 ClientStorageErrorr::Internal(err)
221 }
222}
223
224#[derive(Debug, Deserialize, Serialize)]
226pub struct StorageProxyMap {
227 pub bottle_id: i64,
228 pub handle: ClientStorageThreadHandle,
229}
230
231#[derive(Debug, Deserialize, Serialize)]
232pub enum ClientStorageThreadMessage {
233 ObtainBottleMap {
234 storage_type: StorageType,
235 webview: WebViewId,
236 storage_identifier: StorageIdentifier,
237 origin: ImmutableOrigin,
238 sender: GenericSender<Result<StorageProxyMap, String>>,
239 },
240 CreateDatabase {
241 bottle_id: i64,
242 name: String,
243 sender: GenericSender<Result<PathBuf, String>>,
244 },
245 DeleteDatabase {
246 bottle_id: i64,
247 name: String,
248 sender: GenericSender<Result<(), String>>,
249 },
250 Persisted {
251 origin: ImmutableOrigin,
252 sender: GenericCallback<Result<bool, String>>,
253 },
254 Persist {
255 origin: ImmutableOrigin,
256 permission_granted: bool,
257 sender: GenericCallback<Result<bool, String>>,
258 },
259 Estimate {
260 origin: ImmutableOrigin,
261 sender: GenericCallback<Result<(u64, u64), String>>,
262 },
263 Exit(GenericSender<()>),
264}