mongodb/action/
replace_one.rs

1use std::borrow::Borrow;
2
3use crate::bson::{Bson, Document, RawDocumentBuf};
4use serde::Serialize;
5
6use crate::{
7    coll::options::{Hint, ReplaceOptions, UpdateOptions},
8    collation::Collation,
9    error::Result,
10    operation::Update as Op,
11    options::WriteConcern,
12    results::UpdateResult,
13    ClientSession,
14    Collection,
15};
16
17use super::{action_impl, deeplink, export_doc, option_setters, options_doc, CollRef};
18
19impl<T: Serialize + Send + Sync> Collection<T> {
20    /// Replaces up to one document matching `query` in the collection with `replacement`.
21    ///
22    /// This operation will retry once upon failure if the connection and encountered error support
23    /// retryability. See the documentation
24    /// [here](https://www.mongodb.com/docs/manual/core/retryable-writes/) for more information on
25    /// retryable writes.
26    ///
27    /// `await` will return d[`Result<UpdateResult>`].
28    #[deeplink]
29    #[options_doc(replace_one)]
30    pub fn replace_one(&self, query: Document, replacement: impl Borrow<T>) -> ReplaceOne {
31        ReplaceOne {
32            coll: CollRef::new(self),
33            query,
34            replacement: crate::bson_compat::serialize_to_raw_document_buf(replacement.borrow())
35                .map_err(Into::into),
36            options: None,
37            session: None,
38        }
39    }
40}
41
42#[cfg(feature = "sync")]
43impl<T: Serialize + Send + Sync> crate::sync::Collection<T> {
44    /// Replaces up to one document matching `query` in the collection with `replacement`.
45    ///
46    /// This operation will retry once upon failure if the connection and encountered error support
47    /// retryability. See the documentation
48    /// [here](https://www.mongodb.com/docs/manual/core/retryable-writes/) for more information on
49    /// retryable writes.
50    ///
51    /// [`run`](ReplaceOne::run) will return d[`Result<UpdateResult>`].
52    #[deeplink]
53    #[options_doc(replace_one, sync)]
54    pub fn replace_one(&self, query: Document, replacement: impl Borrow<T>) -> ReplaceOne {
55        self.async_collection.replace_one(query, replacement)
56    }
57}
58
59/// Replace up to one document matching a query.  Construct with [`Collection::replace_one`].
60#[must_use]
61pub struct ReplaceOne<'a> {
62    coll: CollRef<'a>,
63    query: Document,
64    replacement: Result<RawDocumentBuf>,
65    options: Option<ReplaceOptions>,
66    session: Option<&'a mut ClientSession>,
67}
68
69#[option_setters(crate::coll::options::ReplaceOptions)]
70#[export_doc(replace_one)]
71impl<'a> ReplaceOne<'a> {
72    /// Use the provided session when running the operation.
73    pub fn session(mut self, value: impl Into<&'a mut ClientSession>) -> Self {
74        self.session = Some(value.into());
75        self
76    }
77}
78
79#[action_impl]
80impl<'a> Action for ReplaceOne<'a> {
81    type Future = ReplaceOneFuture;
82
83    async fn execute(mut self) -> Result<UpdateResult> {
84        resolve_write_concern_with_session!(self.coll, self.options, self.session.as_ref())?;
85
86        let update = Op::with_replace_raw(
87            self.coll.namespace(),
88            self.query,
89            self.replacement?,
90            false,
91            self.options.map(UpdateOptions::from_replace_options),
92        )?;
93        self.coll
94            .client()
95            .execute_operation(update, self.session)
96            .await
97    }
98}