// 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 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.
_ => 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);