deli/
cursor.rs

1use std::borrow::Borrow;
2
3use serde::{de::DeserializeOwned, Serialize};
4use serde_wasm_bindgen::Serializer;
5
6use crate::{error::Error, model::Model, transaction::Transaction, JSON_SERIALIZER};
7
8/// Cursor on an object store or index
9#[derive(Debug)]
10pub struct Cursor<'t, M, K> {
11    cursor: idb::ManagedCursor,
12    _transaction: &'t Transaction,
13    _marker: std::marker::PhantomData<(M, K)>,
14}
15
16impl<'t, M, K> Cursor<'t, M, K>
17where
18    M: Model,
19    K: Serialize + DeserializeOwned,
20{
21    pub(crate) fn new(cursor: idb::ManagedCursor, transaction: &'t Transaction) -> Self {
22        Self {
23            cursor,
24            _transaction: transaction,
25            _marker: std::marker::PhantomData,
26        }
27    }
28
29    /// Returns the direction of the cursor
30    pub fn direction(&self) -> Result<Option<idb::CursorDirection>, Error> {
31        self.cursor.direction().map_err(Into::into)
32    }
33
34    /// Returns the key at the current position of the cursor
35    pub fn key(&self) -> Result<Option<K>, Error> {
36        let js_value = self.cursor.key()?;
37        js_value
38            .map(serde_wasm_bindgen::from_value)
39            .transpose()
40            .map_err(Into::into)
41    }
42
43    /// Returns the primary key at the current position of the cursor
44    pub fn primary_key(&self) -> Result<Option<M::Key>, Error> {
45        let js_value = self.cursor.primary_key()?;
46        js_value
47            .map(serde_wasm_bindgen::from_value)
48            .transpose()
49            .map_err(Into::into)
50    }
51
52    /// Returns the value at the current position of the cursor
53    pub fn value(&self) -> Result<Option<M>, Error> {
54        let js_value = self.cursor.value()?;
55        js_value
56            .map(serde_wasm_bindgen::from_value)
57            .transpose()
58            .map_err(Into::into)
59    }
60
61    /// Advances the cursor through the next count records in range.
62    pub async fn advance(&mut self, count: u32) -> Result<(), Error> {
63        self.cursor.advance(count).await.map_err(Into::into)
64    }
65
66    /// Advances the cursor to the next record in range matching or after key (if provided).
67    pub async fn next<Q>(&mut self, key: Option<&Q>) -> Result<(), Error>
68    where
69        K: Borrow<Q>,
70        Q: Serialize,
71    {
72        let js_value = key
73            .map(|key| key.serialize(&Serializer::json_compatible()))
74            .transpose()?;
75        self.cursor
76            .next(js_value.as_ref())
77            .await
78            .map_err(Into::into)
79    }
80
81    /// Advances the cursor to the next record in range matching or after key and primary key. Returns an [`Error`] if
82    /// the source is not an [`Index`](crate::Index).
83    pub async fn next_primary_key<Q, R>(&mut self, key: &Q, primary_key: &R) -> Result<(), Error>
84    where
85        K: Borrow<Q>,
86        Q: Serialize,
87        M::Key: Borrow<R>,
88        R: Serialize,
89    {
90        let js_key = key.serialize(&JSON_SERIALIZER)?;
91        let js_primary_key = primary_key.serialize(&JSON_SERIALIZER)?;
92        self.cursor
93            .next_primary_key(&js_key, &js_primary_key)
94            .await
95            .map_err(Into::into)
96    }
97
98    /// Updates the value at the current position of the cursor
99    pub async fn update<V>(&mut self, value: &V) -> Result<M, Error>
100    where
101        M: Borrow<V>,
102        V: Serialize,
103    {
104        let js_value = value.serialize(&JSON_SERIALIZER)?;
105        let updated_js_value = self.cursor.update(&js_value).await?;
106        serde_wasm_bindgen::from_value(updated_js_value).map_err(Into::into)
107    }
108
109    /// Deletes the value at the current position of the cursor
110    pub async fn delete(&mut self) -> Result<(), Error> {
111        self.cursor.delete().await.map_err(Into::into)
112    }
113}