use std::marker::PhantomData;
use bson::Document;
use mongodb::options::{Collation, Hint, ReplaceOptions, WriteConcern};
use crate::collection::Collection;
use crate::filter::{AsFilter, Filter};
use crate::r#async::Client;
#[derive(Clone)]
pub struct Replace<C: Collection> {
filter: Option<Document>,
options: ReplaceOptions,
query_type: std::marker::PhantomData<C>,
}
impl<C: Collection> Default for Replace<C> {
fn default() -> Self {
Self::new()
}
}
impl<C: Collection> Replace<C> {
pub fn new() -> Self {
Self {
filter: None,
options: ReplaceOptions::default(),
query_type: PhantomData,
}
}
pub fn bypass_document_validation(mut self, enable: bool) -> Self {
self.options.bypass_document_validation = Some(enable);
self
}
pub fn collation(mut self, collation: Collation) -> Self {
self.options.collation = Some(collation);
self
}
pub fn filter<F>(mut self, filter: F) -> crate::Result<Self>
where
C: AsFilter<F>,
F: Filter,
{
self.filter = Some(filter.into_document()?);
Ok(self)
}
pub fn hint(mut self, value: Hint) -> Self {
self.options.hint = Some(value);
self
}
pub fn upsert(mut self, enable: bool) -> Self {
self.options.upsert = Some(enable);
self
}
pub fn write_concern(mut self, concern: WriteConcern) -> Self {
self.options.write_concern = Some(concern);
self
}
pub async fn query(self, client: &Client, document: C) -> crate::Result<bool> {
let filter = match self.filter {
Some(f) => f,
None => Document::new(),
};
let result = client
.database()
.collection(C::COLLECTION)
.replace_one(filter, document.into_document()?, self.options)
.await
.map_err(crate::error::mongodb)?;
if result.modified_count > 0 {
return Ok(true);
}
Ok(false)
}
#[cfg(feature = "blocking")]
pub fn blocking(self, client: &crate::blocking::Client, document: C) -> crate::Result<bool> {
let filter = match self.filter {
Some(f) => f,
None => bson::Document::new(),
};
let resp = client.execute(crate::blocking::Request::Replace(
C::COLLECTION,
filter,
document.into_document()?,
self.options,
))?;
if let crate::blocking::Response::Replace(r) = resp {
if r.modified_count > 0 {
return Ok(true);
}
return Ok(false);
}
Err(crate::error::runtime(
"incorrect response from blocking client",
))
}
}