Skip to content

RUST-754 Accept impl Borrow<T> in insert and replace methods #331

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions src/coll/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod batch;
pub mod options;

use std::{fmt, fmt::Debug, sync::Arc};
use std::{borrow::Borrow, fmt, fmt::Debug, sync::Arc};

use futures::StreamExt;
use serde::{
Expand Down Expand Up @@ -539,11 +539,11 @@ where
async fn find_one_and_replace_common(
&self,
filter: Document,
replacement: T,
replacement: impl Borrow<T>,
options: impl Into<Option<FindOneAndReplaceOptions>>,
session: impl Into<Option<&mut ClientSession>>,
) -> Result<Option<T>> {
let replacement = to_document(&replacement)?;
let replacement = to_document(replacement.borrow())?;

let mut options = options.into();
resolve_options!(self, options, [write_concern]);
Expand All @@ -562,7 +562,7 @@ where
pub async fn find_one_and_replace(
&self,
filter: Document,
replacement: T,
replacement: impl Borrow<T>,
options: impl Into<Option<FindOneAndReplaceOptions>>,
) -> Result<Option<T>> {
self.find_one_and_replace_common(filter, replacement, options, None)
Expand All @@ -579,7 +579,7 @@ where
pub async fn find_one_and_replace_with_session(
&self,
filter: Document,
replacement: T,
replacement: impl Borrow<T>,
options: impl Into<Option<FindOneAndReplaceOptions>>,
session: &mut ClientSession,
) -> Result<Option<T>> {
Expand Down Expand Up @@ -643,13 +643,13 @@ where

async fn insert_many_common(
&self,
docs: impl IntoIterator<Item = T>,
docs: impl IntoIterator<Item = impl Borrow<T>>,
options: impl Into<Option<InsertManyOptions>>,
mut session: Option<&mut ClientSession>,
) -> Result<InsertManyResult> {
let docs: ser::Result<Vec<Document>> = docs
.into_iter()
.map(|doc| bson::to_document(&doc))
.map(|doc| bson::to_document(doc.borrow()))
.collect();
let mut docs: Vec<Document> = docs?;

Expand Down Expand Up @@ -739,7 +739,7 @@ where
/// retryable writes.
pub async fn insert_many(
&self,
docs: impl IntoIterator<Item = T>,
docs: impl IntoIterator<Item = impl Borrow<T>>,
options: impl Into<Option<InsertManyOptions>>,
) -> Result<InsertManyResult> {
self.insert_many_common(docs, options, None).await
Expand All @@ -753,7 +753,7 @@ where
/// retryable writes.
pub async fn insert_many_with_session(
&self,
docs: impl IntoIterator<Item = T>,
docs: impl IntoIterator<Item = impl Borrow<T>>,
options: impl Into<Option<InsertManyOptions>>,
session: &mut ClientSession,
) -> Result<InsertManyResult> {
Expand All @@ -762,11 +762,11 @@ where

async fn insert_one_common(
&self,
doc: T,
doc: impl Borrow<T>,
options: impl Into<Option<InsertOneOptions>>,
session: impl Into<Option<&mut ClientSession>>,
) -> Result<InsertOneResult> {
let doc = to_document(&doc)?;
let doc = to_document(doc.borrow())?;

let mut options = options.into();
resolve_options!(self, options, [write_concern]);
Expand All @@ -791,7 +791,7 @@ where
/// retryable writes.
pub async fn insert_one(
&self,
doc: T,
doc: impl Borrow<T>,
options: impl Into<Option<InsertOneOptions>>,
) -> Result<InsertOneResult> {
self.insert_one_common(doc, options, None).await
Expand All @@ -805,7 +805,7 @@ where
/// retryable writes.
pub async fn insert_one_with_session(
&self,
doc: T,
doc: impl Borrow<T>,
options: impl Into<Option<InsertOneOptions>>,
session: &mut ClientSession,
) -> Result<InsertOneResult> {
Expand All @@ -815,11 +815,11 @@ where
async fn replace_one_common(
&self,
query: Document,
replacement: T,
replacement: impl Borrow<T>,
options: impl Into<Option<ReplaceOptions>>,
session: impl Into<Option<&mut ClientSession>>,
) -> Result<UpdateResult> {
let replacement = to_document(&replacement)?;
let replacement = to_document(replacement.borrow())?;

bson_util::replacement_document_check(&replacement)?;

Expand All @@ -845,7 +845,7 @@ where
pub async fn replace_one(
&self,
query: Document,
replacement: T,
replacement: impl Borrow<T>,
options: impl Into<Option<ReplaceOptions>>,
) -> Result<UpdateResult> {
self.replace_one_common(query, replacement, options, None)
Expand All @@ -862,7 +862,7 @@ where
pub async fn replace_one_with_session(
&self,
query: Document,
replacement: T,
replacement: impl Borrow<T>,
options: impl Into<Option<ReplaceOptions>>,
session: &mut ClientSession,
) -> Result<UpdateResult> {
Expand Down
3 changes: 1 addition & 2 deletions src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,7 @@ impl AsyncRuntime {
#[cfg(any(feature = "sync", test))]
pub(crate) fn block_on<F, T>(self, fut: F) -> T
where
F: Future<Output = T> + Send,
T: Send,
F: Future<Output = T>,
{
#[cfg(all(feature = "tokio-runtime", not(feature = "async-std-runtime")))]
{
Expand Down
43 changes: 21 additions & 22 deletions src/sync/coll.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
use std::{
fmt::Debug,
marker::{Send, Sync},
};
use std::{borrow::Borrow, fmt::Debug};

use serde::{de::DeserializeOwned, Serialize};

Expand Down Expand Up @@ -76,14 +73,14 @@ use crate::{
#[derive(Clone, Debug)]
pub struct Collection<T>
where
T: Serialize + DeserializeOwned + Unpin + Debug + Send + Sync,
T: Serialize + DeserializeOwned + Unpin + Debug,
{
async_collection: AsyncCollection<T>,
}

impl<T> Collection<T>
where
T: Serialize + DeserializeOwned + Unpin + Debug + Send + Sync,
T: Serialize + DeserializeOwned + Unpin + Debug,
{
pub(crate) fn new(async_collection: AsyncCollection<T>) -> Self {
Self { async_collection }
Expand All @@ -92,7 +89,7 @@ where
/// Gets a clone of the `Collection` with a different type `U`.
pub fn clone_with_type<U>(&self) -> Collection<U>
where
U: Serialize + DeserializeOwned + Unpin + Debug + Send + Sync,
U: Serialize + DeserializeOwned + Unpin + Debug,
{
Collection::new(self.async_collection.clone_with_type())
}
Expand Down Expand Up @@ -497,10 +494,9 @@ where
/// retryable writes.
pub fn insert_many(
&self,
docs: impl IntoIterator<Item = T>,
docs: impl IntoIterator<Item = impl Borrow<T>>,
options: impl Into<Option<InsertManyOptions>>,
) -> Result<InsertManyResult> {
let docs: Vec<T> = docs.into_iter().collect();
RUNTIME.block_on(self.async_collection.insert_many(docs, options.into()))
}

Expand All @@ -512,11 +508,10 @@ where
/// retryable writes.
pub fn insert_many_with_session(
&self,
docs: impl IntoIterator<Item = T>,
docs: impl IntoIterator<Item = impl Borrow<T>>,
options: impl Into<Option<InsertManyOptions>>,
session: &mut ClientSession,
) -> Result<InsertManyResult> {
let docs: Vec<T> = docs.into_iter().collect();
RUNTIME.block_on(self.async_collection.insert_many_with_session(
docs,
options.into(),
Expand All @@ -532,10 +527,13 @@ where
/// retryable writes.
pub fn insert_one(
&self,
doc: T,
doc: impl Borrow<T>,
options: impl Into<Option<InsertOneOptions>>,
) -> Result<InsertOneResult> {
RUNTIME.block_on(self.async_collection.insert_one(doc, options.into()))
RUNTIME.block_on(
self.async_collection
.insert_one(doc.borrow(), options.into()),
)
}

/// Inserts `doc` into the collection using the provided `ClientSession`.
Expand All @@ -546,12 +544,12 @@ where
/// retryable writes.
pub fn insert_one_with_session(
&self,
doc: T,
doc: impl Borrow<T>,
options: impl Into<Option<InsertOneOptions>>,
session: &mut ClientSession,
) -> Result<InsertOneResult> {
RUNTIME.block_on(self.async_collection.insert_one_with_session(
doc,
doc.borrow(),
options.into(),
session,
))
Expand All @@ -566,13 +564,14 @@ where
pub fn replace_one(
&self,
query: Document,
replacement: T,
replacement: impl Borrow<T>,
options: impl Into<Option<ReplaceOptions>>,
) -> Result<UpdateResult> {
RUNTIME.block_on(
self.async_collection
.replace_one(query, replacement, options.into()),
)
RUNTIME.block_on(self.async_collection.replace_one(
query,
replacement.borrow(),
options.into(),
))
}

/// Replaces up to one document matching `query` in the collection with `replacement` using the
Expand All @@ -585,13 +584,13 @@ where
pub fn replace_one_with_session(
&self,
query: Document,
replacement: T,
replacement: impl Borrow<T>,
options: impl Into<Option<ReplaceOptions>>,
session: &mut ClientSession,
) -> Result<UpdateResult> {
RUNTIME.block_on(self.async_collection.replace_one_with_session(
query,
replacement,
replacement.borrow(),
options.into(),
session,
))
Expand Down
14 changes: 7 additions & 7 deletions src/sync/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,14 @@ use crate::{
#[derive(Debug)]
pub struct Cursor<T>
where
T: DeserializeOwned + Unpin + Send,
T: DeserializeOwned + Unpin,
{
async_cursor: AsyncCursor<T>,
}

impl<T> Cursor<T>
where
T: DeserializeOwned + Unpin + Send,
T: DeserializeOwned + Unpin,
{
pub(crate) fn new(async_cursor: AsyncCursor<T>) -> Self {
Self { async_cursor }
Expand All @@ -87,7 +87,7 @@ where

impl<T> Iterator for Cursor<T>
where
T: DeserializeOwned + Unpin + Send,
T: DeserializeOwned + Unpin,
{
type Item = Result<T>;

Expand Down Expand Up @@ -118,14 +118,14 @@ where
#[derive(Debug)]
pub struct SessionCursor<T>
where
T: DeserializeOwned + Unpin + Send,
T: DeserializeOwned + Unpin,
{
async_cursor: AsyncSessionCursor<T>,
}

impl<T> SessionCursor<T>
where
T: DeserializeOwned + Unpin + Send,
T: DeserializeOwned + Unpin,
{
pub(crate) fn new(async_cursor: AsyncSessionCursor<T>) -> Self {
Self { async_cursor }
Expand All @@ -149,14 +149,14 @@ where
/// This updates the buffer of the parent `SessionCursor` when dropped.
pub struct SessionCursorHandle<'cursor, 'session, T = Document>
where
T: DeserializeOwned + Unpin + Send,
T: DeserializeOwned + Unpin,
{
async_handle: AsyncSessionCursorHandle<'cursor, 'session, T>,
}

impl<T> Iterator for SessionCursorHandle<'_, '_, T>
where
T: DeserializeOwned + Unpin + Send,
T: DeserializeOwned + Unpin,
{
type Item = Result<T>;

Expand Down
9 changes: 3 additions & 6 deletions src/sync/db.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
use std::{
fmt::Debug,
marker::{Send, Sync},
};
use std::fmt::Debug;

use serde::{de::DeserializeOwned, Serialize};

Expand Down Expand Up @@ -95,7 +92,7 @@ impl Database {
/// used repeatedly without incurring any costs from I/O.
pub fn collection<T>(&self, name: &str) -> Collection<T>
where
T: Serialize + DeserializeOwned + Unpin + Debug + Send + Sync,
T: Serialize + DeserializeOwned + Unpin + Debug,
{
Collection::new(self.async_database.collection(name))
}
Expand All @@ -112,7 +109,7 @@ impl Database {
options: CollectionOptions,
) -> Collection<T>
where
T: Serialize + DeserializeOwned + Unpin + Debug + Send + Sync,
T: Serialize + DeserializeOwned + Unpin + Debug,
{
Collection::new(self.async_database.collection_with_options(name, options))
}
Expand Down
9 changes: 3 additions & 6 deletions src/sync/test.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
use std::{
fmt::Debug,
marker::{Send, Sync},
};
use std::fmt::Debug;

use pretty_assertions::assert_eq;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
Expand Down Expand Up @@ -30,7 +27,7 @@ fn init_db_and_coll(client: &Client, db_name: &str, coll_name: &str) -> Collecti

fn init_db_and_typed_coll<T>(client: &Client, db_name: &str, coll_name: &str) -> Collection<T>
where
T: Serialize + DeserializeOwned + Unpin + Debug + Send + Sync,
T: Serialize + DeserializeOwned + Unpin + Debug,
{
let coll = client.database(db_name).collection(coll_name);
drop_collection(&coll);
Expand All @@ -39,7 +36,7 @@ where

pub fn drop_collection<T>(coll: &Collection<T>)
where
T: Serialize + DeserializeOwned + Unpin + Debug + Send + Sync,
T: Serialize + DeserializeOwned + Unpin + Debug,
{
match coll.drop(None).as_ref().map_err(|e| &e.kind) {
Err(ErrorKind::CommandError(CommandError { code: 26, .. })) | Ok(_) => {}
Expand Down
2 changes: 1 addition & 1 deletion src/test/coll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ async fn empty_insert() {
.database(function_name!())
.collection::<Document>(function_name!());
match coll
.insert_many(Vec::new(), None)
.insert_many(Vec::<Document>::new(), None)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In certain cases, this will make type inference more difficult and require the usage of type arguments, such as in this case. I think this is worth it over taking in just &T though, which rules out owned values and other smart-pointer types from being passed in (e.g. Arc, Box). I think in most cases users won't be relying on the concrete type in these methods and the annotations won't be necessary.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this seems like a fairly similar situation to the one I outlined during the Serde work where the concrete type is needed in the method parameter to assign types to generic function calls like Vec::new. Our consensus was that a situation like that would be quite rare, and since we're doing a 2.0 I think it's fine to break this/require these types in the future (especially given that the only place this shows up within our testing is on this call which results in an error anyway).

.await
.expect_err("should get error")
.kind
Expand Down