use std::{borrow::Borrow, ops::Deref};
use crate::bson::{Bson, RawDocumentBuf};
use serde::Serialize;
use crate::{
coll::options::{InsertManyOptions, InsertOneOptions},
error::{convert_insert_many_error, Result},
operation::Insert as Op,
options::WriteConcern,
results::InsertOneResult,
ClientSession,
Collection,
};
use super::{action_impl, deeplink, export_doc, option_setters, options_doc, CollRef};
impl<T: Serialize + Send + Sync> Collection<T> {
#[deeplink]
#[options_doc(insert_one)]
pub fn insert_one(&self, doc: impl Borrow<T>) -> InsertOne {
InsertOne {
coll: CollRef::new(self),
doc: crate::bson_compat::serialize_to_raw_document_buf(doc.borrow())
.map_err(Into::into),
options: None,
session: None,
}
}
}
#[cfg(feature = "sync")]
impl<T: Serialize + Send + Sync> crate::sync::Collection<T> {
#[deeplink]
#[options_doc(insert_one, sync)]
pub fn insert_one(&self, doc: impl Borrow<T>) -> InsertOne {
self.async_collection.insert_one(doc)
}
}
#[must_use]
pub struct InsertOne<'a> {
coll: CollRef<'a>,
doc: Result<RawDocumentBuf>,
options: Option<InsertOneOptions>,
session: Option<&'a mut ClientSession>,
}
#[option_setters(crate::coll::options::InsertOneOptions)]
#[export_doc(insert_one)]
impl<'a> InsertOne<'a> {
pub fn session(mut self, value: impl Into<&'a mut ClientSession>) -> Self {
self.session = Some(value.into());
self
}
}
#[action_impl]
impl<'a> Action for InsertOne<'a> {
type Future = InsertOneFuture;
async fn execute(mut self) -> Result<InsertOneResult> {
resolve_write_concern_with_session!(self.coll, self.options, self.session.as_ref())?;
let doc = self.doc?;
let insert = Op::new(
self.coll.namespace(),
vec![doc.deref()],
self.options.map(InsertManyOptions::from_insert_one_options),
self.coll.client().should_auto_encrypt().await,
);
self.coll
.client()
.execute_operation(insert, self.session)
.await
.map(InsertOneResult::from_insert_many_result)
.map_err(convert_insert_many_error)
}
}