idb_sys/object_store/
key_path.rs

1use js_sys::Array;
2use wasm_bindgen::{JsCast, JsValue};
3
4use crate::Error;
5
6/// Represents key path of an object store
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum KeyPath {
9    /// Key path with single key
10    Single(String),
11    /// Key path with multiple keys
12    Array(Vec<String>),
13}
14
15impl KeyPath {
16    /// Creates new single key path
17    pub fn new_single(key_path: &str) -> Self {
18        Self::Single(key_path.to_owned())
19    }
20
21    /// Creates new multiple key path
22    pub fn new_array<'a>(key_path_array: impl IntoIterator<Item = &'a str>) -> Self {
23        Self::Array(key_path_array.into_iter().map(ToOwned::to_owned).collect())
24    }
25}
26
27impl From<KeyPath> for JsValue {
28    fn from(key_path: KeyPath) -> Self {
29        match key_path {
30            KeyPath::Single(key_path) => JsValue::from_str(&key_path),
31            KeyPath::Array(key_path_array) => {
32                let key_path: Array = key_path_array
33                    .iter()
34                    .map(|s| JsValue::from_str(s))
35                    .collect();
36                key_path.into()
37            }
38        }
39    }
40}
41
42impl TryFrom<JsValue> for KeyPath {
43    type Error = Error;
44
45    fn try_from(key_path: JsValue) -> Result<Self, Self::Error> {
46        if key_path.is_string() {
47            let key_path = key_path.as_string().ok_or(Error::InvalidKeyPath)?;
48
49            Ok(KeyPath::Single(key_path))
50        } else {
51            let key_path: Array = key_path
52                .dyn_into()
53                .map_err(|value| Error::UnexpectedJsType("Array", value))?;
54
55            let mut key_paths = vec![];
56
57            for i in 0..key_path.length() {
58                if let Some(k) = key_path.get(i).as_string() {
59                    key_paths.push(k);
60                }
61            }
62
63            Ok(KeyPath::Array(key_paths))
64        }
65    }
66}