obj/asynchronous/collection.rs
1//! `AsyncCollection` — async-facing wrapper over a runtime-named
2//! read-only [`crate::Collection`] handle.
3//!
4//! Construction is infallible (see [`crate::Db::collection`]); each
5//! async method opens a fresh blocking [`crate::Db::collection`]
6//! handle inside the [`blocking`] pool and dispatches one of its
7//! read-only methods.
8//!
9//! Writes via a runtime-named handle are intentionally out of scope —
10//! Phase 1B (M11 #94) limits the runtime accessor to reads. Use
11//! [`crate::asynchronous::AsyncDb::transaction`] +
12//! [`crate::WriteTxn::collection`] for the typed-write path.
13
14use std::marker::PhantomData;
15use std::sync::Arc;
16
17use obj_core::{Document, Id, Result};
18
19use crate::asynchronous::db::unblock;
20use crate::Db;
21
22/// Async-facing wrapper over a runtime-named read-only collection
23/// handle.
24///
25/// Cheap to clone — holds one `Arc<Db>` + the collection name.
26#[derive(Debug)]
27pub struct AsyncCollection<T> {
28 db: Arc<Db>,
29 name: String,
30 _phantom: PhantomData<fn() -> T>,
31}
32
33impl<T> Clone for AsyncCollection<T> {
34 fn clone(&self) -> Self {
35 Self {
36 db: Arc::clone(&self.db),
37 name: self.name.clone(),
38 _phantom: PhantomData,
39 }
40 }
41}
42
43impl<T> AsyncCollection<T>
44where
45 T: Document + Send + 'static,
46{
47 pub(crate) fn lazy(db: Arc<Db>, name: String) -> Self {
48 Self {
49 db,
50 name,
51 _phantom: PhantomData,
52 }
53 }
54
55 /// Async sibling of [`crate::Collection::get`]. Opens a private
56 /// read transaction inside the blocking task.
57 ///
58 /// # Errors
59 ///
60 /// As [`crate::Collection::get`].
61 pub async fn get(&self, id: Id) -> Result<Option<T>> {
62 let db = Arc::clone(&self.db);
63 let name = self.name.clone();
64 unblock(move || db.collection::<T>(name).get(id)).await
65 }
66
67 /// Async sibling of [`crate::Collection::all`].
68 ///
69 /// # Errors
70 ///
71 /// As [`crate::Collection::all`].
72 pub async fn all(&self) -> Result<Vec<(Id, T)>> {
73 let db = Arc::clone(&self.db);
74 let name = self.name.clone();
75 unblock(move || db.collection::<T>(name).all()).await
76 }
77
78 /// Async sibling of [`crate::Collection::count_all`].
79 ///
80 /// # Errors
81 ///
82 /// As [`crate::Collection::count_all`].
83 pub async fn count_all(&self) -> Result<u64> {
84 let db = Arc::clone(&self.db);
85 let name = self.name.clone();
86 unblock(move || db.collection::<T>(name).count_all()).await
87 }
88
89 /// Async sibling of [`crate::Collection::find_unique`].
90 ///
91 /// # Errors
92 ///
93 /// As [`crate::Collection::find_unique`].
94 pub async fn find_unique<K>(&self, index_name: &str, key: K) -> Result<Option<T>>
95 where
96 K: Into<obj_core::codec::Dynamic> + Send + 'static,
97 {
98 let db = Arc::clone(&self.db);
99 let name = self.name.clone();
100 let index_name = index_name.to_owned();
101 unblock(move || db.collection::<T>(name).find_unique(&index_name, key)).await
102 }
103}