script/dom/
idbkeyrange.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use dom_struct::dom_struct;
6use js::gc::MutableHandleValue;
7use js::rust::HandleValue;
8use net_traits::indexeddb_thread::IndexedDBKeyRange;
9use script_bindings::codegen::GenericBindings::IDBKeyRangeBinding::IDBKeyRangeMethods;
10use script_bindings::root::DomRoot;
11use script_bindings::script_runtime::CanGc;
12
13use crate::dom::bindings::error::{Error, Fallible};
14use crate::dom::bindings::import::module::SafeJSContext;
15use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
16use crate::dom::globalscope::GlobalScope;
17use crate::indexed_db::{convert_value_to_key, key_type_to_jsval};
18
19#[dom_struct]
20pub struct IDBKeyRange {
21    reflector_: Reflector,
22    #[no_trace]
23    inner: IndexedDBKeyRange,
24}
25
26impl IDBKeyRange {
27    pub fn new_inherited(inner: IndexedDBKeyRange) -> Self {
28        IDBKeyRange {
29            reflector_: Reflector::new(),
30            inner,
31        }
32    }
33
34    pub fn new(global: &GlobalScope, inner: IndexedDBKeyRange, can_gc: CanGc) -> DomRoot<Self> {
35        reflect_dom_object(Box::new(IDBKeyRange::new_inherited(inner)), global, can_gc)
36    }
37
38    pub fn inner(&self) -> &IndexedDBKeyRange {
39        &self.inner
40    }
41}
42
43impl IDBKeyRangeMethods<crate::DomTypeHolder> for IDBKeyRange {
44    // https://www.w3.org/TR/IndexedDB-2/#dom-idbkeyrange-lower
45    fn Lower(&self, cx: SafeJSContext, answer: MutableHandleValue) {
46        if let Some(lower) = self.inner.lower.as_ref() {
47            key_type_to_jsval(cx, lower, answer);
48        }
49    }
50
51    // https://www.w3.org/TR/IndexedDB-2/#dom-idbkeyrange-upper
52    fn Upper(&self, cx: SafeJSContext, answer: MutableHandleValue) {
53        if let Some(upper) = self.inner.upper.as_ref() {
54            key_type_to_jsval(cx, upper, answer);
55        }
56    }
57
58    // https://www.w3.org/TR/IndexedDB-2/#dom-idbkeyrange-loweropen
59    fn LowerOpen(&self) -> bool {
60        self.inner.lower_open
61    }
62
63    // https://www.w3.org/TR/IndexedDB-2/#dom-idbkeyrange-upperopen
64    fn UpperOpen(&self) -> bool {
65        self.inner.upper_open
66    }
67
68    // https://www.w3.org/TR/IndexedDB-2/#dom-idbkeyrange-only
69    fn Only(
70        cx: SafeJSContext,
71        global: &GlobalScope,
72        value: HandleValue,
73    ) -> Fallible<DomRoot<IDBKeyRange>> {
74        let key = convert_value_to_key(cx, value, None)?;
75        let inner = IndexedDBKeyRange::only(key);
76        Ok(IDBKeyRange::new(global, inner, CanGc::note()))
77    }
78
79    // https://www.w3.org/TR/IndexedDB-2/#dom-idbkeyrange-lowerbound
80    fn LowerBound(
81        cx: SafeJSContext,
82        global: &GlobalScope,
83        lower: HandleValue,
84        open: bool,
85    ) -> Fallible<DomRoot<IDBKeyRange>> {
86        let key = convert_value_to_key(cx, lower, None)?;
87        let inner = IndexedDBKeyRange::lower_bound(key, open);
88        Ok(IDBKeyRange::new(global, inner, CanGc::note()))
89    }
90
91    // https://www.w3.org/TR/IndexedDB-2/#dom-idbkeyrange-upperbound
92    fn UpperBound(
93        cx: SafeJSContext,
94        global: &GlobalScope,
95        upper: HandleValue,
96        open: bool,
97    ) -> Fallible<DomRoot<IDBKeyRange>> {
98        let key = convert_value_to_key(cx, upper, None)?;
99        let inner = IndexedDBKeyRange::upper_bound(key, open);
100        Ok(IDBKeyRange::new(global, inner, CanGc::note()))
101    }
102
103    // https://www.w3.org/TR/IndexedDB-2/#dom-idbkeyrange-bound
104    fn Bound(
105        cx: SafeJSContext,
106        global: &GlobalScope,
107        lower: HandleValue,
108        upper: HandleValue,
109        lower_open: bool,
110        upper_open: bool,
111    ) -> Fallible<DomRoot<IDBKeyRange>> {
112        // Step 1. Let lowerKey be the result of running the steps to convert a value to a key with
113        // lower. Rethrow any exceptions.
114        // Step 2. If lowerKey is invalid, throw a "DataError" DOMException.
115        let lower_key = convert_value_to_key(cx, lower, None)?;
116
117        // Step 3. Let upperKey be the result of running the steps to convert a value to a key with
118        // upper. Rethrow any exceptions.
119        // Step 4. If upperKey is invalid, throw a "DataError" DOMException.
120        let upper_key = convert_value_to_key(cx, upper, None)?;
121
122        // Step 5. If lowerKey is greater than upperKey, throw a "DataError" DOMException.
123        if lower_key > upper_key {
124            return Err(Error::Data);
125        }
126
127        // Step 6. Create and return a new key range with lower bound set to lowerKey, lower open
128        // flag set if lowerOpen is true, upper bound set to upperKey and upper open flag set if
129        // upperOpen is true.
130        let inner =
131            IndexedDBKeyRange::new(Some(lower_key), Some(upper_key), lower_open, upper_open);
132        Ok(IDBKeyRange::new(global, inner, CanGc::note()))
133    }
134
135    // https://www.w3.org/TR/IndexedDB-2/#dom-idbkeyrange-_includes
136    fn Includes(&self, cx: SafeJSContext, value: HandleValue) -> Fallible<bool> {
137        let key = convert_value_to_key(cx, value, None)?;
138        if self.inner.contains(&key) {
139            return Ok(true);
140        }
141        Ok(false)
142    }
143}