mongodb/action/
list_indexes.rs

1use std::{marker::PhantomData, time::Duration};
2
3use crate::{action::ActionSession, bson::Bson};
4use futures_util::stream::TryStreamExt;
5
6use crate::{
7    coll::options::ListIndexesOptions,
8    error::Result,
9    operation::ListIndexes as Op,
10    ClientSession,
11    Collection,
12    Cursor,
13    IndexModel,
14    SessionCursor,
15};
16
17use super::{
18    action_impl,
19    deeplink,
20    export_doc,
21    option_setters,
22    options_doc,
23    CollRef,
24    ExplicitSession,
25    ImplicitSession,
26    ListNames,
27    ListSpecifications,
28};
29
30impl<T> Collection<T>
31where
32    T: Send + Sync,
33{
34    /// Lists all indexes on this collection.
35    ///
36    /// `await` will return d[`Result<Cursor<IndexModel>>`] (or
37    /// d[`Result<SessionCursor<IndexModel>>`] if a `ClientSession` is provided).
38    #[deeplink]
39    #[options_doc(list_indexes)]
40    pub fn list_indexes(&self) -> ListIndexes<'_> {
41        ListIndexes {
42            coll: CollRef::new(self),
43            options: None,
44            session: ImplicitSession,
45            _mode: PhantomData,
46        }
47    }
48
49    /// Gets the names of all indexes on the collection.
50    ///
51    /// `await` will return d[`Result<Vec<String>>`].
52    #[deeplink]
53    #[options_doc(list_index_names)]
54    pub fn list_index_names(&self) -> ListIndexes<'_, ListNames> {
55        ListIndexes {
56            coll: CollRef::new(self),
57            options: None,
58            session: ImplicitSession,
59            _mode: PhantomData,
60        }
61    }
62}
63
64#[cfg(feature = "sync")]
65impl<T> crate::sync::Collection<T>
66where
67    T: Send + Sync,
68{
69    /// Lists all indexes on this collection.
70    ///
71    /// [`run`](ListIndexes::run) will return d[`Result<crate::sync::Cursor<IndexModel>>`] (or
72    /// d[`Result<crate::sync::SessionCursor<IndexModel>>`] if a `ClientSession` is provided).
73    #[deeplink]
74    #[options_doc(list_indexes, "run")]
75    pub fn list_indexes(&self) -> ListIndexes<'_> {
76        self.async_collection.list_indexes()
77    }
78
79    /// Gets the names of all indexes on the collection.
80    ///
81    /// [`run`](ListIndexes::run) will return d[`Result<Vec<String>>`].
82    #[deeplink]
83    #[options_doc(list_index_names, "run")]
84    pub fn list_index_names(&self) -> ListIndexes<'_, ListNames> {
85        self.async_collection.list_index_names()
86    }
87}
88
89/// List indexes on a collection.  Construct with [`Collection::list_indexes`] or
90/// [`Collection::list_index_names`].
91#[must_use]
92pub struct ListIndexes<'a, Mode = ListSpecifications, Session = ImplicitSession> {
93    coll: CollRef<'a>,
94    options: Option<ListIndexesOptions>,
95    session: Session,
96    _mode: PhantomData<Mode>,
97}
98
99#[option_setters(crate::coll::options::ListIndexesOptions)]
100#[export_doc(list_indexes, extra = [session, batch])]
101impl<'a, Session: ActionSession<'a>> ListIndexes<'a, ListSpecifications, Session> {
102    async fn exec_generic<C: crate::cursor::NewCursor>(self) -> Result<C> {
103        let mut op = Op::new(self.coll.namespace(), self.options);
104        self.coll
105            .client()
106            .execute_cursor_operation(&mut op, self.session.into_opt_session())
107            .await
108    }
109}
110
111impl ListIndexes<'_, ListSpecifications, ImplicitSession> {
112    /// Execute the listIndexes command, returning a cursor that provides results in zero-copy raw
113    /// batches.
114    pub async fn batch(self) -> Result<crate::raw_batch_cursor::RawBatchCursor> {
115        self.exec_generic().await
116    }
117}
118
119impl<'a> ListIndexes<'a, ListSpecifications, ExplicitSession<'a>> {
120    /// Execute the listIndexes command, returning a cursor that provides results in zero-copy raw
121    /// batches.
122    pub async fn batch(self) -> Result<crate::raw_batch_cursor::SessionRawBatchCursor> {
123        self.exec_generic().await
124    }
125}
126
127#[option_setters(crate::coll::options::ListIndexesOptions)]
128#[export_doc(list_index_names, extra = [session])]
129impl<Session> ListIndexes<'_, ListNames, Session> {}
130
131impl<'a, Mode> ListIndexes<'a, Mode, ImplicitSession> {
132    /// Use the provided session when running the operation.
133    pub fn session(
134        self,
135        value: impl Into<&'a mut ClientSession>,
136    ) -> ListIndexes<'a, Mode, ExplicitSession<'a>> {
137        ListIndexes {
138            coll: self.coll,
139            options: self.options,
140            session: ExplicitSession(value.into()),
141            _mode: PhantomData,
142        }
143    }
144}
145
146#[action_impl(sync = crate::sync::Cursor<IndexModel>)]
147impl<'a> Action for ListIndexes<'a, ListSpecifications, ImplicitSession> {
148    type Future = ListIndexesFuture;
149
150    async fn execute(self) -> Result<Cursor<IndexModel>> {
151        self.exec_generic().await
152    }
153}
154
155#[action_impl(sync = crate::sync::SessionCursor<IndexModel>)]
156impl<'a> Action for ListIndexes<'a, ListSpecifications, ExplicitSession<'a>> {
157    type Future = ListIndexesSessionFuture;
158
159    async fn execute(self) -> Result<SessionCursor<IndexModel>> {
160        let mut op = Op::new(self.coll.namespace(), self.options);
161        self.coll
162            .client()
163            .execute_cursor_operation(&mut op, Some(self.session.0))
164            .await
165    }
166}
167
168#[action_impl]
169impl<'a> Action for ListIndexes<'a, ListNames, ImplicitSession> {
170    type Future = ListIndexNamesFuture;
171
172    async fn execute(self) -> Result<Vec<String>> {
173        let inner = ListIndexes {
174            coll: self.coll,
175            options: self.options,
176            session: self.session,
177            _mode: PhantomData::<ListSpecifications>,
178        };
179        let cursor = inner.await?;
180        cursor
181            .try_filter_map(|index| futures_util::future::ok(index.get_name()))
182            .try_collect()
183            .await
184    }
185}
186
187#[action_impl]
188impl<'a> Action for ListIndexes<'a, ListNames, ExplicitSession<'a>> {
189    type Future = ListIndexNamesSessionFuture;
190
191    async fn execute(self) -> Result<Vec<String>> {
192        let session = self.session.0;
193        let inner = ListIndexes {
194            coll: self.coll,
195            options: self.options,
196            session: ExplicitSession(&mut *session),
197            _mode: PhantomData::<ListSpecifications>,
198        };
199        let mut cursor = inner.await?;
200        let stream = cursor.stream(session);
201        stream
202            .try_filter_map(|index| futures_util::future::ok(index.get_name()))
203            .try_collect()
204            .await
205    }
206}