1extern crate cfg_if;
2extern crate futures;
3extern crate js_sys;
4extern crate n5;
5extern crate serde_json;
6extern crate wasm_bindgen;
7extern crate wasm_bindgen_futures;
8extern crate web_sys;
9
10mod utils;
11
12use std::io::{
13 Error,
14 ErrorKind,
15};
16
17use js_sys::Promise;
18use futures::{future, Future};
19use wasm_bindgen::prelude::*;
20use wasm_bindgen_futures::future_to_promise;
21
22use n5::prelude::*;
23
24
25pub mod http_fetch;
26
27
28pub trait N5PromiseReader {
29 fn get_version(&self) -> Promise;
31
32 fn get_dataset_attributes(&self, path_name: &str) -> Promise;
33
34 fn exists(&self, path_name: &str) -> Promise;
35
36 fn dataset_exists(&self, path_name: &str) -> Promise;
37
38 fn read_block(
39 &self,
40 path_name: &str,
41 data_attrs: &wrapped::DatasetAttributes,
42 grid_position: Vec<i64>
43 ) -> Promise;
44
45 fn list_attributes(&self, path_name: &str) -> Promise;
46}
47
48impl<T> N5PromiseReader for T where T: N5AsyncReader {
49 fn get_version(&self) -> Promise {
50 let to_return = self.get_version()
51 .map(|v| JsValue::from(wrapped::Version(v)));
52
53 future_to_promise(map_future_error_wasm(to_return))
54 }
55
56 fn get_dataset_attributes(&self, path_name: &str) -> Promise {
57 let to_return = self.get_dataset_attributes(path_name)
58 .map(|da| JsValue::from(wrapped::DatasetAttributes(da)));
59
60 future_to_promise(map_future_error_wasm(to_return))
61 }
62
63 fn exists(&self, path_name: &str) -> Promise {
64 let to_return = self.exists(path_name)
65 .map(JsValue::from);
66
67 future_to_promise(map_future_error_wasm(to_return))
68 }
69
70 fn dataset_exists(&self, path_name: &str) -> Promise {
71 let to_return = self.dataset_exists(path_name)
72 .map(JsValue::from);
73
74 future_to_promise(map_future_error_wasm(to_return))
75 }
76
77 fn read_block(
78 &self,
79 path_name: &str,
80 data_attrs: &wrapped::DatasetAttributes,
81 grid_position: Vec<i64>
82 ) -> Promise {
83 match data_attrs.0.get_data_type() {
84 DataType::UINT8 => future_to_promise(map_future_error_wasm(
87 self.read_block::<u8>(path_name, &data_attrs.0, grid_position)
88 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockUINT8::from))))),
89 DataType::UINT16 => future_to_promise(map_future_error_wasm(
90 self.read_block::<u16>(path_name, &data_attrs.0, grid_position)
91 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockUINT16::from))))),
92 DataType::UINT32 => future_to_promise(map_future_error_wasm(
93 self.read_block::<u32>(path_name, &data_attrs.0, grid_position)
94 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockUINT32::from))))),
95 DataType::UINT64 => future_to_promise(map_future_error_wasm(
96 self.read_block::<u64>(path_name, &data_attrs.0, grid_position)
97 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockUINT64::from))))),
98 DataType::INT8 => future_to_promise(map_future_error_wasm(
99 self.read_block::<i8>(path_name, &data_attrs.0, grid_position)
100 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockINT8::from))))),
101 DataType::INT16 => future_to_promise(map_future_error_wasm(
102 self.read_block::<i16>(path_name, &data_attrs.0, grid_position)
103 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockINT16::from))))),
104 DataType::INT32 => future_to_promise(map_future_error_wasm(
105 self.read_block::<i32>(path_name, &data_attrs.0, grid_position)
106 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockINT32::from))))),
107 DataType::INT64 => future_to_promise(map_future_error_wasm(
108 self.read_block::<i64>(path_name, &data_attrs.0, grid_position)
109 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockINT64::from))))),
110 DataType::FLOAT32 => future_to_promise(map_future_error_wasm(
111 self.read_block::<f32>(path_name, &data_attrs.0, grid_position)
112 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockFLOAT32::from))))),
113 DataType::FLOAT64 => future_to_promise(map_future_error_wasm(
114 self.read_block::<f64>(path_name, &data_attrs.0, grid_position)
115 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockFLOAT64::from))))),
116 }
117 }
118
119 fn list_attributes(
120 &self,
121 path_name: &str,
122 ) -> Promise {
123
124 let to_return = self.list_attributes(path_name)
126 .map(|v| JsValue::from_serde(&v).unwrap());
127
128 future_to_promise(map_future_error_wasm(to_return))
129 }
130}
131
132
133pub trait N5PromiseEtagReader {
134 fn block_etag(
135 &self,
136 path_name: &str,
137 data_attrs: &wrapped::DatasetAttributes,
138 grid_position: Vec<i64>
139 ) -> Promise;
140
141 fn read_block_with_etag(
142 &self,
143 path_name: &str,
144 data_attrs: &wrapped::DatasetAttributes,
145 grid_position: Vec<i64>
146 ) -> Promise;
147}
148
149impl<T> N5PromiseEtagReader for T where T: N5AsyncEtagReader {
150 fn block_etag(
151 &self,
152 path_name: &str,
153 data_attrs: &wrapped::DatasetAttributes,
154 grid_position: Vec<i64>
155 ) -> Promise {
156 let to_return = self.block_etag(path_name, &data_attrs.0, grid_position)
157 .map(JsValue::from);
158
159 future_to_promise(map_future_error_wasm(to_return))
160 }
161
162 fn read_block_with_etag(
163 &self,
164 path_name: &str,
165 data_attrs: &wrapped::DatasetAttributes,
166 grid_position: Vec<i64>
167 ) -> Promise {
168 match data_attrs.0.get_data_type() {
169 DataType::UINT8 => future_to_promise(map_future_error_wasm(
172 self.read_block_with_etag::<u8>(path_name, &data_attrs.0, grid_position)
173 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockUINT8::from))))),
174 DataType::UINT16 => future_to_promise(map_future_error_wasm(
175 self.read_block_with_etag::<u16>(path_name, &data_attrs.0, grid_position)
176 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockUINT16::from))))),
177 DataType::UINT32 => future_to_promise(map_future_error_wasm(
178 self.read_block_with_etag::<u32>(path_name, &data_attrs.0, grid_position)
179 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockUINT32::from))))),
180 DataType::UINT64 => future_to_promise(map_future_error_wasm(
181 self.read_block_with_etag::<u64>(path_name, &data_attrs.0, grid_position)
182 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockUINT64::from))))),
183 DataType::INT8 => future_to_promise(map_future_error_wasm(
184 self.read_block_with_etag::<i8>(path_name, &data_attrs.0, grid_position)
185 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockINT8::from))))),
186 DataType::INT16 => future_to_promise(map_future_error_wasm(
187 self.read_block_with_etag::<i16>(path_name, &data_attrs.0, grid_position)
188 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockINT16::from))))),
189 DataType::INT32 => future_to_promise(map_future_error_wasm(
190 self.read_block_with_etag::<i32>(path_name, &data_attrs.0, grid_position)
191 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockINT32::from))))),
192 DataType::INT64 => future_to_promise(map_future_error_wasm(
193 self.read_block_with_etag::<i64>(path_name, &data_attrs.0, grid_position)
194 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockINT64::from))))),
195 DataType::FLOAT32 => future_to_promise(map_future_error_wasm(
196 self.read_block_with_etag::<f32>(path_name, &data_attrs.0, grid_position)
197 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockFLOAT32::from))))),
198 DataType::FLOAT64 => future_to_promise(map_future_error_wasm(
199 self.read_block_with_etag::<f64>(path_name, &data_attrs.0, grid_position)
200 .map(|maybe_block| JsValue::from(maybe_block.map(VecDataBlockFLOAT64::from))))),
201 }
202 }
203}
204
205
206pub trait N5AsyncReader {
210 fn get_version(&self) -> Box<Future<Item = n5::Version, Error = Error>>;
211
212 fn get_dataset_attributes(&self, path_name: &str) ->
213 Box<Future<Item = n5::DatasetAttributes, Error = Error>>;
214
215 fn exists(&self, path_name: &str) -> Box<Future<Item = bool, Error = Error>>;
216
217 fn dataset_exists(&self, path_name: &str) -> Box<Future<Item = bool, Error = Error>> {
218 Box::new(self.exists(path_name).join(
219 self.get_dataset_attributes(path_name)
220 .map(|_| true)
221 .or_else(|_| futures::future::ok(false))
222 ).map(|(exists, has_attr)| exists && has_attr))
223 }
224
225 fn read_block<T>(
226 &self,
227 path_name: &str,
228 data_attrs: &DatasetAttributes,
229 grid_position: Vec<i64>
230 ) -> Box<Future<Item = Option<VecDataBlock<T>>, Error = Error>>
231 where DataType: n5::DataBlockCreator<T>,
232 VecDataBlock<T>: DataBlock<T>,
233 T: Clone + 'static;
234
235 fn list(&self, path_name: &str) -> Box<Future<Item = Vec<String>, Error = Error>>;
236
237 fn list_attributes(&self, path_name: &str) -> Box<Future<Item = serde_json::Value, Error = Error>>;
238}
239
240
241pub trait N5AsyncEtagReader {
242 fn block_etag(
243 &self,
244 path_name: &str,
245 data_attrs: &DatasetAttributes,
246 grid_position: Vec<i64>
247 ) -> Box<Future<Item = Option<String>, Error = Error>>;
248
249 fn read_block_with_etag<T>(
250 &self,
251 path_name: &str,
252 data_attrs: &DatasetAttributes,
253 grid_position: Vec<i64>
254 ) -> Box<Future<Item = Option<(VecDataBlock<T>, Option<String>)>, Error = Error>>
255 where DataType: n5::DataBlockCreator<T>,
256 VecDataBlock<T>: DataBlock<T>,
257 T: Clone + 'static;
258}
259
260
261fn map_future_error_rust<F: Future<Item = T, Error = JsValue>, T>(future: F)
262 -> impl Future<Item = T, Error = Error> {
263 future.map_err(convert_jsvalue_error)
264}
265
266fn map_future_error_wasm<F: Future<Item = T, Error = Error>, T>(future: F)
267 -> impl Future<Item = T, Error = JsValue> {
268 future.map_err(|error| {
269 let js_error = js_sys::Error::new(&format!("{:?}", error));
270 JsValue::from(js_error)
271 })
272}
273
274fn convert_jsvalue_error(error: JsValue) -> Error {
275 Error::new(std::io::ErrorKind::Other, format!("{:?}", error))
276}
277
278
279pub mod wrapped {
280 use super::*;
281
282 #[wasm_bindgen]
283 pub struct Version(pub(crate) n5::Version);
284
285 #[wasm_bindgen]
286 impl Version {
287 pub fn to_string(&self) -> String {
288 self.0.to_string()
289 }
290 }
291
292 #[wasm_bindgen]
293 pub struct DatasetAttributes(pub(crate) n5::DatasetAttributes);
294
295 #[wasm_bindgen]
296 impl DatasetAttributes {
297 pub fn get_dimensions(&self) -> Vec<i64> {
298 self.0.get_dimensions().to_owned()
299 }
300
301 pub fn get_block_size(&self) -> Vec<i32> {
302 self.0.get_block_size().to_owned()
303 }
304
305 pub fn get_data_type(&self) -> String {
306 self.0.get_data_type().to_string()
307 }
308
309 pub fn get_compression(&self) -> String {
310 self.0.get_compression().to_string()
311 }
312
313 pub fn get_ndim(&self) -> usize {
314 self.0.get_ndim()
315 }
316
317 pub fn get_num_elements(&self) -> usize {
319 self.0.get_num_elements()
320 }
321
322 pub fn get_block_num_elements(&self) -> usize {
324 self.0.get_block_num_elements()
325 }
326 }
327}
328
329macro_rules! data_block_monomorphizer {
330 ($d_name:ident, $d_type:ty) => {
331 #[wasm_bindgen]
332 pub struct $d_name(VecDataBlock<$d_type>, Option<String>);
333
334 impl From<VecDataBlock<$d_type>> for $d_name {
335 fn from(block: VecDataBlock<$d_type>) -> Self {
336 $d_name(block, None)
337 }
338 }
339
340 impl From<(VecDataBlock<$d_type>, Option<String>)> for $d_name {
341 fn from((block, etag): (VecDataBlock<$d_type>, Option<String>)) -> Self {
342 $d_name(block, etag)
343 }
344 }
345
346 #[wasm_bindgen]
347 impl $d_name {
348 pub fn get_size(&self) -> Vec<i32> {
349 self.0.get_size().to_owned()
350 }
351
352 pub fn get_grid_position(&self) -> Vec<i64> {
353 self.0.get_grid_position().to_owned()
354 }
355
356 pub fn get_data(&self) -> Vec<$d_type> {
357 self.0.get_data().to_owned()
358 }
359
360 pub fn into_data(self) -> Vec<$d_type> {
361 self.0.into()
362 }
363
364 pub fn get_num_elements(&self) -> i32 {
365 self.0.get_num_elements()
366 }
367
368 pub fn get_etag(&self) -> Option<String> {
369 self.1.to_owned()
370 }
371 }
372 }
373}
374
375data_block_monomorphizer!(VecDataBlockUINT8, u8);
376data_block_monomorphizer!(VecDataBlockUINT16, u16);
377data_block_monomorphizer!(VecDataBlockUINT32, u32);
378data_block_monomorphizer!(VecDataBlockUINT64, u64);
379data_block_monomorphizer!(VecDataBlockINT8, i8);
380data_block_monomorphizer!(VecDataBlockINT16, i16);
381data_block_monomorphizer!(VecDataBlockINT32, i32);
382data_block_monomorphizer!(VecDataBlockINT64, i64);
383data_block_monomorphizer!(VecDataBlockFLOAT32, f32);
384data_block_monomorphizer!(VecDataBlockFLOAT64, f64);