Skip to content

Commit a8972b9

Browse files
abr-egnmlokr
andauthored
fixing the find or delete serde inconsistency (#948) (#955)
Co-authored-by: Jakub Doka <[email protected]>
1 parent b8446b2 commit a8972b9

File tree

3 files changed

+44
-10
lines changed

3 files changed

+44
-10
lines changed

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ time = "0.3.9"
195195
tokio = { version = ">= 0.0.0", features = ["fs"] }
196196
tracing-subscriber = "0.3.16"
197197
regex = "1.6.0"
198+
serde-hex = "0.1.0"
198199

199200
[package.metadata.docs.rs]
200201
rustdoc-args = ["--cfg", "docsrs"]
@@ -210,4 +211,4 @@ features = [
210211
"aws-auth",
211212
"tracing-unstable",
212213
"in-use-encryption-unstable"
213-
]
214+
]

src/operation/find_and_modify.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ mod test;
44

55
use std::fmt::Debug;
66

7+
use bson::{from_slice, RawBson};
78
use serde::{de::DeserializeOwned, Deserialize};
89

910
use self::options::FindAndModifyOptions;
1011
use crate::{
11-
bson::{doc, from_document, Bson, Document},
12+
bson::{doc, Document},
1213
bson_util,
1314
cmap::{Command, RawCommandResponse, StreamDescription},
1415
coll::{
@@ -133,11 +134,15 @@ where
133134
response: RawCommandResponse,
134135
_description: &StreamDescription,
135136
) -> Result<Self::O> {
137+
#[derive(Debug, Deserialize)]
138+
pub(crate) struct Response {
139+
value: RawBson,
140+
}
136141
let response: Response = response.body()?;
137142

138143
match response.value {
139-
Bson::Document(doc) => Ok(Some(from_document(doc)?)),
140-
Bson::Null => Ok(None),
144+
RawBson::Document(doc) => Ok(Some(from_slice(doc.as_bytes())?)),
145+
RawBson::Null => Ok(None),
141146
other => Err(ErrorKind::InvalidResponse {
142147
message: format!(
143148
"expected document for value field of findAndModify response, but instead got \
@@ -157,8 +162,3 @@ where
157162
Retryability::Write
158163
}
159164
}
160-
161-
#[derive(Debug, Deserialize)]
162-
pub(crate) struct Response {
163-
value: Bson,
164-
}

src/test/client.rs

+34-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::{borrow::Cow, collections::HashMap, sync::Arc, time::Duration};
22

33
use bson::Document;
4-
use serde::Deserialize;
4+
use serde::{Deserialize, Serialize};
55
use tokio::sync::{RwLockReadGuard, RwLockWriteGuard};
66

77
use crate::{
@@ -976,6 +976,39 @@ async fn manual_shutdown_immediate_with_resources() {
976976
assert!(events.get_command_started_events(&["delete"]).is_empty());
977977
}
978978

979+
#[cfg_attr(feature = "tokio-runtime", tokio::test)]
980+
#[cfg_attr(feature = "async-std-runtime", async_std::test)]
981+
async fn find_one_and_delete_serde_consistency() {
982+
let client = Client::test_builder().build().await;
983+
984+
let coll = client
985+
.database("find_one_and_delete_serde_consistency")
986+
.collection("test");
987+
988+
#[derive(Debug, Serialize, Deserialize)]
989+
struct Foo {
990+
#[serde(with = "serde_hex::SerHexSeq::<serde_hex::StrictPfx>")]
991+
problematic: Vec<u8>,
992+
}
993+
994+
let doc = Foo {
995+
problematic: vec![0, 1, 2, 3, 4, 5, 6, 7],
996+
};
997+
998+
coll.insert_one(&doc, None).await.unwrap();
999+
let rec: Foo = coll.find_one(doc! {}, None).await.unwrap().unwrap();
1000+
assert_eq!(doc.problematic, rec.problematic);
1001+
let rec: Foo = coll
1002+
.find_one_and_delete(doc! {}, None)
1003+
.await
1004+
.unwrap()
1005+
.unwrap();
1006+
assert_eq!(doc.problematic, rec.problematic);
1007+
1008+
let nothing = coll.find_one_and_delete(doc! {}, None).await.unwrap();
1009+
assert!(nothing.is_none());
1010+
}
1011+
9791012
// Verifies that `Client::warm_connection_pool` succeeds.
9801013
#[cfg_attr(feature = "tokio-runtime", tokio::test)]
9811014
#[cfg_attr(feature = "async-std-runtime", async_std::test)]

0 commit comments

Comments
 (0)