Skip to content

Commit 08c5b33

Browse files
committed
RUST-679 avoid cloning errors in cursor implementation
1 parent 59b976e commit 08c5b33

File tree

3 files changed

+35
-32
lines changed

3 files changed

+35
-32
lines changed

src/cursor/common.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use futures::{Future, Stream};
1010

1111
use crate::{
1212
bson::Document,
13-
error::{ErrorKind, Result},
13+
error::{Error, ErrorKind, Result},
1414
options::StreamAddress,
1515
results::GetMoreResult,
1616
Client,
@@ -73,12 +73,13 @@ impl<T: GetMoreProvider> Stream for GenericCursor<T> {
7373
if let Some(future) = self.provider.executing_future() {
7474
match Pin::new(future).poll(cx) {
7575
// If a result is ready, retrieve the buffer and update the exhausted status.
76-
Poll::Ready(mut get_more_result) => {
77-
let buffer_result = get_more_result.take_buffer();
78-
self.exhausted = get_more_result.exhausted();
76+
Poll::Ready(get_more_result) => {
77+
let exhausted = get_more_result.exhausted();
78+
let (result, session) = get_more_result.into_parts();
7979

80-
self.provider.clear_execution(get_more_result);
81-
self.buffer = buffer_result?;
80+
self.exhausted = exhausted;
81+
self.provider.clear_execution(session, exhausted);
82+
self.buffer = result?.batch;
8283
}
8384
Poll::Pending => return Poll::Pending,
8485
}
@@ -113,24 +114,23 @@ pub(super) trait GetMoreProvider: Unpin {
113114
fn executing_future(&mut self) -> Option<&mut Self::GetMoreFuture>;
114115

115116
/// Clear out any state remaining from previous getMore executions.
116-
fn clear_execution(&mut self, result: Self::GetMoreResult);
117+
fn clear_execution(
118+
&mut self,
119+
session: <Self::GetMoreResult as GetMoreProviderResult>::Session,
120+
exhausted: bool,
121+
);
117122

118123
/// Start executing a new getMore if one isn't already in flight.
119124
fn start_execution(&mut self, spec: CursorInformation, client: Client);
120125
}
121126

122127
/// Trait describing results returned from a `GetMoreProvider`.
123128
pub(super) trait GetMoreProviderResult {
124-
/// A result containing a mutable reference to the raw getMore result.
125-
fn as_mut(&mut self) -> Result<&mut GetMoreResult>;
129+
type Session;
126130

127-
/// A result containing a reference to the raw getMore result.
128-
fn as_ref(&self) -> Result<&GetMoreResult>;
131+
fn as_ref(&self) -> std::result::Result<&GetMoreResult, &Error>;
129132

130-
/// Take the buffer from the getMore result.
131-
fn take_buffer(&mut self) -> Result<VecDeque<Document>> {
132-
self.as_mut().map(|res| std::mem::take(&mut res.batch))
133-
}
133+
fn into_parts(self) -> (Result<GetMoreResult>, Self::Session);
134134

135135
/// Whether the response from the server indicated the cursor was exhausted or not.
136136
fn exhausted(&self) -> bool {

src/cursor/mod.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use serde::de::DeserializeOwned;
1414
use crate::{
1515
bson::{from_document, Document},
1616
client::ClientSession,
17-
error::Result,
17+
error::{Error, Result},
1818
operation::GetMore,
1919
results::GetMoreResult,
2020
Client,
@@ -157,11 +157,14 @@ struct ImplicitSessionGetMoreResult {
157157
}
158158

159159
impl GetMoreProviderResult for ImplicitSessionGetMoreResult {
160-
fn as_mut(&mut self) -> Result<&mut GetMoreResult> {
161-
self.get_more_result.as_mut().map_err(|e| e.clone())
160+
type Session = Option<ClientSession>;
161+
162+
fn as_ref(&self) -> std::result::Result<&GetMoreResult, &Error> {
163+
self.get_more_result.as_ref()
162164
}
163-
fn as_ref(&self) -> Result<&GetMoreResult> {
164-
self.get_more_result.as_ref().map_err(|e| e.clone())
165+
166+
fn into_parts(self) -> (Result<GetMoreResult>, Self::Session) {
167+
(self.get_more_result, self.session)
165168
}
166169
}
167170

@@ -194,12 +197,12 @@ impl GetMoreProvider for ImplicitSessionGetMoreProvider {
194197
}
195198
}
196199

197-
fn clear_execution(&mut self, result: Self::GetMoreResult) {
200+
fn clear_execution(&mut self, session: Option<ClientSession>, exhausted: bool) {
198201
// If cursor is exhausted, immediately return implicit session to the pool.
199-
if result.get_more_result.map(|r| r.exhausted).unwrap_or(false) {
202+
if exhausted {
200203
*self = Self::Done;
201204
} else {
202-
*self = Self::Idle(result.session)
205+
*self = Self::Idle(session)
203206
}
204207
}
205208

src/cursor/session.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
bson::Document,
88
client::ClientSession,
99
cursor::CursorSpecification,
10-
error::Result,
10+
error::{Error, Result},
1111
operation::GetMore,
1212
results::GetMoreResult,
1313
Client,
@@ -127,10 +127,8 @@ impl<'session> GetMoreProvider for ExplicitSessionGetMoreProvider<'session> {
127127
}
128128
}
129129

130-
fn clear_execution(&mut self, result: Self::GetMoreResult) {
131-
*self = Self::Idle(MutableSessionReference {
132-
reference: result.session,
133-
})
130+
fn clear_execution(&mut self, session: &'session mut ClientSession, _exhausted: bool) {
131+
*self = Self::Idle(MutableSessionReference { reference: session })
134132
}
135133

136134
fn start_execution(&mut self, info: CursorInformation, client: Client) {
@@ -161,12 +159,14 @@ struct ExecutionResult<'session> {
161159
}
162160

163161
impl<'session> GetMoreProviderResult for ExecutionResult<'session> {
164-
fn as_mut(&mut self) -> Result<&mut GetMoreResult> {
165-
self.get_more_result.as_mut().map_err(|e| e.clone())
162+
type Session = &'session mut ClientSession;
163+
164+
fn as_ref(&self) -> std::result::Result<&GetMoreResult, &Error> {
165+
self.get_more_result.as_ref()
166166
}
167167

168-
fn as_ref(&self) -> Result<&GetMoreResult> {
169-
self.get_more_result.as_ref().map_err(|e| e.clone())
168+
fn into_parts(self) -> (Result<GetMoreResult>, Self::Session) {
169+
(self.get_more_result, self.session)
170170
}
171171
}
172172

0 commit comments

Comments
 (0)