use crate::{
transaction::transaction_request,
utils::{
array_to_vec, make_key_range, make_key_range_from_slice, map_count_err, map_count_res,
map_get_err, none_if_undefined, slice_to_array,
},
};
use futures_util::future::{Either, FutureExt};
use std::{future::Future, marker::PhantomData, ops::RangeBounds};
use web_sys::{wasm_bindgen::JsValue, IdbIndex};
pub struct Index<Err> {
sys: IdbIndex,
_phantom: PhantomData<Err>,
}
impl<Err> Index<Err> {
pub(crate) fn from_sys(sys: IdbIndex) -> Index<Err> {
Index {
sys,
_phantom: PhantomData,
}
}
pub fn count_in(
&self,
range: impl RangeBounds<JsValue>,
) -> impl Future<Output = crate::Result<usize, Err>> {
let range = match make_key_range(range) {
Ok(range) => range,
Err(e) => return Either::Left(std::future::ready(Err(e))),
};
match self.sys.count_with_key(&range) {
Ok(count_req) => {
Either::Right(transaction_request(count_req).map(|res| res.map(map_count_res)))
}
Err(e) => Either::Left(std::future::ready(Err(map_count_err(e)))),
}
}
pub fn get(
&self,
key: &[&JsValue],
) -> impl Future<Output = crate::Result<Option<JsValue>, Err>> {
match self.sys.get(&slice_to_array(key)) {
Ok(get_req) => {
Either::Right(transaction_request(get_req).map(|res| res.map(none_if_undefined)))
}
Err(err) => Either::Left(std::future::ready(Err(map_get_err(err)))),
}
}
pub fn get_first_in<'a>(
&self,
range: impl RangeBounds<[&'a JsValue]>,
) -> impl Future<Output = crate::Result<Option<JsValue>, Err>> {
let range = match make_key_range_from_slice(range) {
Ok(range) => range,
Err(e) => return Either::Left(std::future::ready(Err(e))),
};
match self.sys.get(&range) {
Ok(get_req) => {
Either::Right(transaction_request(get_req).map(|res| res.map(none_if_undefined)))
}
Err(e) => Either::Left(std::future::ready(Err(map_get_err(e)))),
}
}
pub fn get_all(
&self,
limit: Option<u32>,
) -> impl Future<Output = crate::Result<Vec<JsValue>, Err>> {
let get_req = match limit {
None => self.sys.get_all(),
Some(limit) => self
.sys
.get_all_with_key_and_limit(&JsValue::UNDEFINED, limit),
};
match get_req {
Ok(get_req) => {
Either::Right(transaction_request(get_req).map(|res| res.map(array_to_vec)))
}
Err(err) => Either::Left(std::future::ready(Err(map_get_err(err)))),
}
}
pub fn get_all_in<'a>(
&self,
range: impl RangeBounds<[&'a JsValue]>,
limit: Option<u32>,
) -> impl Future<Output = crate::Result<Vec<JsValue>, Err>> {
let range = match make_key_range_from_slice(range) {
Ok(range) => range,
Err(e) => return Either::Left(std::future::ready(Err(e))),
};
let get_req = match limit {
None => self.sys.get_all_with_key(&range),
Some(limit) => self.sys.get_all_with_key_and_limit(&range, limit),
};
match get_req {
Ok(get_req) => {
Either::Right(transaction_request(get_req).map(|res| res.map(array_to_vec)))
}
Err(err) => Either::Left(std::future::ready(Err(map_get_err(err)))),
}
}
pub fn get_first_key_in<'a>(
&self,
range: impl RangeBounds<[&'a JsValue]>,
) -> impl Future<Output = crate::Result<Option<JsValue>, Err>> {
let range = match make_key_range_from_slice(range) {
Ok(range) => range,
Err(e) => return Either::Left(std::future::ready(Err(e))),
};
match self.sys.get_key(&range) {
Ok(get_req) => {
Either::Right(transaction_request(get_req).map(|res| res.map(none_if_undefined)))
}
Err(err) => Either::Left(std::future::ready(Err(map_get_err(err)))),
}
}
pub fn get_all_keys(
&self,
limit: Option<u32>,
) -> impl Future<Output = crate::Result<Vec<JsValue>, Err>> {
let get_req = match limit {
None => self.sys.get_all_keys(),
Some(limit) => self
.sys
.get_all_keys_with_key_and_limit(&JsValue::UNDEFINED, limit),
};
match get_req {
Ok(get_req) => {
Either::Right(transaction_request(get_req).map(|res| res.map(array_to_vec)))
}
Err(err) => Either::Left(std::future::ready(Err(map_get_err(err)))),
}
}
pub fn get_all_keys_in<'a>(
&self,
range: impl RangeBounds<[&'a JsValue]>,
limit: Option<u32>,
) -> impl Future<Output = crate::Result<Vec<JsValue>, Err>> {
let range = match make_key_range_from_slice(range) {
Ok(range) => range,
Err(e) => return Either::Left(std::future::ready(Err(e))),
};
let get_req = match limit {
None => self.sys.get_all_keys_with_key(&range),
Some(limit) => self.sys.get_all_keys_with_key_and_limit(&range, limit),
};
match get_req {
Ok(get_req) => {
Either::Right(transaction_request(get_req).map(|res| res.map(array_to_vec)))
}
Err(err) => Either::Left(std::future::ready(Err(map_get_err(err)))),
}
}
}