1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
#![feature(async_await, await_macro, futures_api)] #![recursion_limit="500"] #[macro_use] extern crate stdweb; use stdweb::PromiseFuture; use stdweb::Value; use stdweb::unstable::TryInto; use stdweb::unstable::TryFrom; pub enum Driver { INDEXEDDB, WEBSQL, LOCALSTORAGE, } impl TryFrom<Driver> for Value { type Error = (); fn try_from(driver: Driver) -> Result<Value, Self::Error> { match driver { Driver::INDEXEDDB => Ok(js! ( return localforage.INDEXEDDB; )), Driver::WEBSQL => Ok(js! ( return localforage.WEBSQL; )), Driver::LOCALSTORAGE => Ok(js! ( return localforage.LOCALSTORAGE; )), } } } pub struct LocalForage { obj: Value, } pub struct Config { pub name: Option<String>, pub driver: Option<Driver>, pub size: Option<u32>, pub store_name: Option<String>, pub version: Option<String>, pub description: Option<String>, } impl LocalForage { pub fn new(name: String) -> Self { LocalForage { obj: js! ( return localforage.createInstance({name: @{name}}); ) } } pub fn get_item<T>(&self, key: &str) -> PromiseFuture<T> where <T as TryFrom<Value>>::Error: std::fmt::Debug, T: TryFrom<Value> + 'static { js! ( return @{&self.obj}.getItem(@{key}); ).try_into().unwrap() } pub fn set_item<T>(&self, key: &str, value: T) -> PromiseFuture<T> where T: TryInto<Value> + TryFrom<Value> + 'static, <T as TryInto<Value>>::Error: std::fmt::Debug, <T as TryFrom<Value>>::Error: std::fmt::Debug { let tmp: Value = value.try_into().unwrap(); js! ( return @{&self.obj}.setItem(@{key}, @{tmp}); ).try_into().unwrap() } pub fn remove_item(&self, key: &str) -> PromiseFuture<()> { js! ( return @{&self.obj}.removeItem(@{key}); ).try_into().unwrap() } pub fn clear(&self) -> PromiseFuture<()> { js! ( return @{&self.obj}.clear(); ).try_into().unwrap() } pub fn length(&self) -> PromiseFuture<u64> { js! ( return @{&self.obj}.length(); ).try_into().unwrap() } pub fn keys(&self) -> PromiseFuture<Vec<String>> { js! ( return @{&self.obj}.keys(); ).try_into().unwrap() } pub fn drop_instance(&self) -> PromiseFuture<()> { js! ( return @{&self.obj}.dropInstance(); ).try_into().unwrap() } pub fn set_driver(&self, driver: Driver) { js! { @{&self.obj}.setDriver(@{Value::try_from(driver).unwrap()}); }; } pub fn config(&self, config: Config) { js! { let config = {}; if @{config.name.is_some()} { config.name = @{config.name.unwrap()}; } if @{config.driver.is_some()} { config.driver = @{Value::try_from(config.driver.unwrap()).unwrap()}; } if @{config.size.is_some()} { config.size = @{config.size.unwrap()}; } if @{config.store_name.is_some()} { config.name = @{config.store_name.unwrap()}; } if @{config.version.is_some()} { config.version = @{config.version.unwrap()}; } if @{config.description.is_some()} { config.description = @{config.description.unwrap()}; } @{&self.obj}.config(config); }; } }