idb_sys/
key_range.rs

1use wasm_bindgen::{JsCast, JsValue};
2use web_sys::IdbKeyRange;
3
4use crate::Error;
5
6/// Represents a continuous interval over some data type that is used for keys.
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct KeyRange {
9    inner: IdbKeyRange,
10}
11
12impl KeyRange {
13    /// Returns a new [`KeyRange`] spanning only key.
14    pub fn only(value: &JsValue) -> Result<Self, Error> {
15        let inner = IdbKeyRange::only(value).map_err(Error::KeyRangeCreateFailed)?;
16
17        Ok(Self { inner })
18    }
19
20    /// Returns a new [`KeyRange`] spanning from lower to upper. If `lower_open` is true, `lower` is not included in the
21    /// range. If `upper_open` is true, `upper` is not included in the range.
22    pub fn bound(
23        lower: &JsValue,
24        upper: &JsValue,
25        lower_open: Option<bool>,
26        upper_open: Option<bool>,
27    ) -> Result<Self, Error> {
28        let inner = IdbKeyRange::bound_with_lower_open_and_upper_open(
29            lower,
30            upper,
31            lower_open.unwrap_or_default(),
32            upper_open.unwrap_or_default(),
33        )
34        .map_err(Error::KeyRangeCreateFailed)?;
35
36        Ok(Self { inner })
37    }
38
39    /// Returns a new [`KeyRange`] starting at key with no upper bound. If `lower_open` is true, key is not included in
40    /// the range.
41    pub fn lower_bound(lower: &JsValue, lower_open: Option<bool>) -> Result<Self, Error> {
42        let inner = IdbKeyRange::lower_bound_with_open(lower, lower_open.unwrap_or_default())
43            .map_err(Error::KeyRangeCreateFailed)?;
44
45        Ok(Self { inner })
46    }
47
48    /// Returns a new [`KeyRange`] with no lower bound and ending at key. If `upper_open` is true, key is not included
49    /// in the range.
50    pub fn upper_bound(upper: &JsValue, upper_open: Option<bool>) -> Result<Self, Error> {
51        let inner = IdbKeyRange::upper_bound_with_open(upper, upper_open.unwrap_or_default())
52            .map_err(Error::KeyRangeCreateFailed)?;
53
54        Ok(Self { inner })
55    }
56
57    /// Returns the range’s lower bound, or undefined if none.
58    pub fn lower(&self) -> Result<JsValue, Error> {
59        self.inner.lower().map_err(Error::KeyRangeBoundNotFound)
60    }
61
62    /// Returns the range’s upper bound, or undefined if none.
63    pub fn upper(&self) -> Result<JsValue, Error> {
64        self.inner.upper().map_err(Error::KeyRangeBoundNotFound)
65    }
66
67    /// Returns the range’s lower open flag.
68    pub fn lower_open(&self) -> bool {
69        self.inner.lower_open()
70    }
71
72    /// Returns the range’s upper open flag.
73    pub fn upper_open(&self) -> bool {
74        self.inner.upper_open()
75    }
76
77    /// Returns true if key is included in the range, and false otherwise.
78    pub fn includes(&self, value: &JsValue) -> Result<bool, Error> {
79        self.inner
80            .includes(value)
81            .map_err(Error::KeyRangeIncludesFailed)
82    }
83}
84
85impl From<IdbKeyRange> for KeyRange {
86    fn from(inner: IdbKeyRange) -> Self {
87        Self { inner }
88    }
89}
90
91impl From<KeyRange> for IdbKeyRange {
92    fn from(key_range: KeyRange) -> Self {
93        key_range.inner
94    }
95}
96
97impl TryFrom<JsValue> for KeyRange {
98    type Error = Error;
99
100    fn try_from(value: JsValue) -> Result<Self, Self::Error> {
101        value
102            .dyn_into::<IdbKeyRange>()
103            .map(Into::into)
104            .map_err(|value| Error::UnexpectedJsType("IdbKeyRange", value))
105    }
106}
107
108impl From<KeyRange> for JsValue {
109    fn from(value: KeyRange) -> Self {
110        value.inner.into()
111    }
112}