// OmegaUpload Web Frontend // Copyright (C) 2021 Edward Shen // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . use std::{hint::unreachable_unchecked, marker::PhantomData}; use gloo_console::log; use js_sys::{Array, JsString, Object}; use wasm_bindgen::JsValue; pub struct IdbObject(Array, PhantomData); impl IdbObject { fn add_tuple(self, key: &str, value: &JsValue) -> IdbObject { let array = Array::new(); array.push(&JsString::from(key)); array.push(value); self.0.push(&array); IdbObject(self.0, PhantomData) } } impl From> for Object { fn from(db_object: IdbObject) -> Self { match Self::from_entries(db_object.as_ref()) { Ok(o) => o, // SAFETY: IdbObject maintains the invariant that it can eventually // be constructed into a JS object. _ => { log!("IdbObject invariant violated?!"); unsafe { unreachable_unchecked() } } } } } impl IdbObject { pub fn new() -> Self { Self(Array::new(), PhantomData) } pub fn archive(self) -> IdbObject { self.add_tuple("type", &JsString::from("archive")) } pub fn video(self) -> IdbObject { self.add_tuple("type", &JsString::from("video")) } pub fn audio(self) -> IdbObject { self.add_tuple("type", &JsString::from("audio")) } pub fn image(self) -> IdbObject { self.add_tuple("type", &JsString::from("image")) } pub fn blob(self) -> IdbObject { self.add_tuple("type", &JsString::from("blob")) } pub fn string(self) -> IdbObject { self.add_tuple("type", &JsString::from("string")) } } impl Default for IdbObject { fn default() -> Self { Self::new() } } impl IdbObject { pub fn expiration_text(self, expires: &str) -> IdbObject { self.add_tuple("expiration", &JsString::from(expires)) } } impl IdbObject { pub fn data(self, value: &JsValue) -> IdbObject { self.add_tuple("data", value) } } impl IdbObject { pub fn extra(self, key: &str, value: impl Into) -> Self { self.add_tuple(key, &value.into()) } } impl AsRef for IdbObject { fn as_ref(&self) -> &JsValue { self.0.as_ref() } } macro_rules! impl_idb_object_state { ($($ident:ident),*) => { pub trait IdbObjectState {} $( pub enum $ident {} impl IdbObjectState for $ident {} )* }; } impl_idb_object_state!(NeedsType, NeedsExpiration, NeedsData, Ready);