Skip to content

Commit 3e6c9fd

Browse files
committed
convert wrappers
1 parent dfb29f2 commit 3e6c9fd

5 files changed

Lines changed: 284 additions & 251 deletions

File tree

driver/src/operation.rs

Lines changed: 214 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -291,12 +291,6 @@ impl<T: Send + Sync> From<&Collection<T>> for OperationTarget {
291291
}
292292
}
293293

294-
pub(crate) trait OperationImpl {
295-
type Kind;
296-
}
297-
298-
pub(crate) struct WithDefaults;
299-
300294
// A mirror of the `Operation` trait, with default behavior where appropriate. Should only be
301295
// implemented by operation types that do not delegate to other operations.
302296
pub(crate) trait OperationWithDefaults: Send + Sync {
@@ -417,10 +411,100 @@ pub(crate) trait OperationWithDefaults: Send + Sync {
417411
type Otel: crate::otel::OtelWitness<Op = Self>;
418412
}
419413

420-
impl<T: OperationWithDefaults + OperationImpl<Kind = WithDefaults>> Operation for T
414+
pub(crate) trait OperationDispatch<Kind> {
415+
type O;
416+
const NAME: &'static CStr;
417+
const ZERO_COPY: bool;
418+
fn build(&mut self, description: &StreamDescription) -> Result<Command>;
419+
fn extract_at_cluster_time(&self, response: &RawDocument) -> Result<Option<Timestamp>>;
420+
fn handle_response<'a>(
421+
&'a self,
422+
response: Cow<'a, RawCommandResponse>,
423+
context: ExecutionContext<'a>,
424+
) -> BoxFuture<'a, Result<Self::O>>;
425+
fn handle_error(&self, error: Error) -> Result<Self::O>;
426+
fn selection_criteria(&self) -> Feature<&SelectionCriteria>;
427+
fn read_concern(&self) -> Feature<&ReadConcern>;
428+
fn write_concern(&self) -> Feature<&WriteConcern>;
429+
fn supports_sessions(&self) -> bool;
430+
fn retryability(&self, options: &ClientOptions) -> Retryability;
431+
fn is_backpressure_retryable(&self, options: &ClientOptions) -> bool;
432+
fn update_for_retry(&mut self, retry: Option<&Retry>);
433+
fn override_criteria(&self) -> OverrideCriteriaFn;
434+
fn pinned_connection(&self) -> Option<&PinnedConnectionHandle>;
435+
fn name(&self) -> &CStr;
436+
fn target(&self) -> OperationTarget;
437+
#[cfg(feature = "opentelemetry")]
438+
type Otel: crate::otel::OtelWitness<Op = Self>;
439+
}
440+
441+
pub(crate) trait OperationImpl {
442+
type Kind;
443+
}
444+
445+
impl<K, T> Operation for T
421446
where
422-
T: Send + Sync,
447+
T: OperationImpl<Kind = K> + OperationDispatch<K> + Send + Sync,
423448
{
449+
type O = <T as OperationDispatch<K>>::O;
450+
const NAME: &'static CStr = <T as OperationDispatch<K>>::NAME;
451+
const ZERO_COPY: bool = <T as OperationDispatch<K>>::ZERO_COPY;
452+
fn build(&mut self, description: &StreamDescription) -> Result<Command> {
453+
<T as OperationDispatch<K>>::build(self, description)
454+
}
455+
fn extract_at_cluster_time(&self, response: &RawDocument) -> Result<Option<Timestamp>> {
456+
<T as OperationDispatch<K>>::extract_at_cluster_time(self, response)
457+
}
458+
fn handle_response<'a>(
459+
&'a self,
460+
response: Cow<'a, RawCommandResponse>,
461+
context: ExecutionContext<'a>,
462+
) -> BoxFuture<'a, Result<Self::O>> {
463+
<T as OperationDispatch<K>>::handle_response(self, response, context)
464+
}
465+
fn handle_error(&self, error: Error) -> Result<Self::O> {
466+
<T as OperationDispatch<K>>::handle_error(self, error)
467+
}
468+
fn selection_criteria(&self) -> Feature<&SelectionCriteria> {
469+
<T as OperationDispatch<K>>::selection_criteria(self)
470+
}
471+
fn read_concern(&self) -> Feature<&ReadConcern> {
472+
<T as OperationDispatch<K>>::read_concern(self)
473+
}
474+
fn write_concern(&self) -> Feature<&WriteConcern> {
475+
<T as OperationDispatch<K>>::write_concern(self)
476+
}
477+
fn supports_sessions(&self) -> bool {
478+
<T as OperationDispatch<K>>::supports_sessions(self)
479+
}
480+
fn retryability(&self, options: &ClientOptions) -> Retryability {
481+
<T as OperationDispatch<K>>::retryability(self, options)
482+
}
483+
fn is_backpressure_retryable(&self, options: &ClientOptions) -> bool {
484+
<T as OperationDispatch<K>>::is_backpressure_retryable(self, options)
485+
}
486+
fn update_for_retry(&mut self, retry: Option<&Retry>) {
487+
<T as OperationDispatch<K>>::update_for_retry(self, retry)
488+
}
489+
fn override_criteria(&self) -> OverrideCriteriaFn {
490+
<T as OperationDispatch<K>>::override_criteria(self)
491+
}
492+
fn pinned_connection(&self) -> Option<&PinnedConnectionHandle> {
493+
<T as OperationDispatch<K>>::pinned_connection(self)
494+
}
495+
fn name(&self) -> &CStr {
496+
<T as OperationDispatch<K>>::name(self)
497+
}
498+
fn target(&self) -> OperationTarget {
499+
<T as OperationDispatch<K>>::target(self)
500+
}
501+
#[cfg(feature = "opentelemetry")]
502+
type Otel = <T as OperationDispatch<K>>::Otel;
503+
}
504+
505+
pub(crate) struct WithDefaults;
506+
507+
impl<T: OperationWithDefaults> OperationDispatch<WithDefaults> for T {
424508
type O = T::O;
425509
const NAME: &'static CStr = T::NAME;
426510
const ZERO_COPY: bool = T::ZERO_COPY;
@@ -477,6 +561,128 @@ where
477561
type Otel = <Self as OperationWithDefaults>::Otel;
478562
}
479563

564+
pub(crate) trait OperationWrapper {
565+
// Required
566+
type Wrapped: Operation;
567+
type O;
568+
#[cfg(feature = "opentelemetry")]
569+
type Otel: crate::otel::OtelWitness<Op = Self>;
570+
571+
fn wrapped(&self) -> &Self::Wrapped;
572+
fn wrapped_mut(&mut self) -> &mut Self::Wrapped;
573+
574+
fn handle_response<'a>(
575+
&'a self,
576+
response: Cow<'a, RawCommandResponse>,
577+
context: ExecutionContext<'a>,
578+
) -> BoxFuture<'a, Result<Self::O>>;
579+
580+
// Delegated to wrapped
581+
const NAME: &'static CStr = Self::Wrapped::NAME;
582+
const ZERO_COPY: bool = Self::Wrapped::ZERO_COPY;
583+
fn build(&mut self, description: &StreamDescription) -> Result<Command> {
584+
self.wrapped_mut().build(description)
585+
}
586+
fn handle_error(&self, error: Error) -> Result<Self::O> {
587+
Err(error)
588+
}
589+
fn extract_at_cluster_time(&self, response: &RawDocument) -> Result<Option<Timestamp>> {
590+
self.wrapped().extract_at_cluster_time(response)
591+
}
592+
fn selection_criteria(&self) -> Feature<&SelectionCriteria> {
593+
self.wrapped().selection_criteria()
594+
}
595+
fn read_concern(&self) -> Feature<&ReadConcern> {
596+
self.wrapped().read_concern()
597+
}
598+
fn write_concern(&self) -> Feature<&WriteConcern> {
599+
self.wrapped().write_concern()
600+
}
601+
fn supports_sessions(&self) -> bool {
602+
self.wrapped().supports_sessions()
603+
}
604+
fn retryability(&self, options: &ClientOptions) -> Retryability {
605+
self.wrapped().retryability(options)
606+
}
607+
fn is_backpressure_retryable(&self, options: &ClientOptions) -> bool {
608+
self.wrapped().is_backpressure_retryable(options)
609+
}
610+
fn update_for_retry(&mut self, retry: Option<&Retry>) {
611+
self.wrapped_mut().update_for_retry(retry);
612+
}
613+
fn override_criteria(&self) -> OverrideCriteriaFn {
614+
self.wrapped().override_criteria()
615+
}
616+
fn pinned_connection(&self) -> Option<&PinnedConnectionHandle> {
617+
self.wrapped().pinned_connection()
618+
}
619+
fn name(&self) -> &CStr {
620+
self.wrapped().name()
621+
}
622+
fn target(&self) -> OperationTarget {
623+
self.wrapped().target()
624+
}
625+
}
626+
627+
pub(crate) struct Wrapper;
628+
629+
impl<T: OperationWrapper> OperationDispatch<Wrapper> for T {
630+
type O = T::O;
631+
const NAME: &'static CStr = T::NAME;
632+
const ZERO_COPY: bool = T::ZERO_COPY;
633+
fn build(&mut self, description: &StreamDescription) -> Result<Command> {
634+
self.build(description)
635+
}
636+
fn extract_at_cluster_time(&self, response: &RawDocument) -> Result<Option<Timestamp>> {
637+
self.extract_at_cluster_time(response)
638+
}
639+
fn handle_response<'a>(
640+
&'a self,
641+
response: Cow<'a, RawCommandResponse>,
642+
context: ExecutionContext<'a>,
643+
) -> BoxFuture<'a, Result<Self::O>> {
644+
self.handle_response(response, context)
645+
}
646+
fn handle_error(&self, error: Error) -> Result<Self::O> {
647+
self.handle_error(error)
648+
}
649+
fn selection_criteria(&self) -> Feature<&SelectionCriteria> {
650+
self.selection_criteria()
651+
}
652+
fn read_concern(&self) -> Feature<&ReadConcern> {
653+
self.read_concern()
654+
}
655+
fn write_concern(&self) -> Feature<&WriteConcern> {
656+
self.write_concern()
657+
}
658+
fn supports_sessions(&self) -> bool {
659+
self.supports_sessions()
660+
}
661+
fn retryability(&self, options: &ClientOptions) -> Retryability {
662+
self.retryability(options)
663+
}
664+
fn is_backpressure_retryable(&self, options: &ClientOptions) -> bool {
665+
self.is_backpressure_retryable(options)
666+
}
667+
fn update_for_retry(&mut self, retry: Option<&Retry>) {
668+
self.update_for_retry(retry)
669+
}
670+
fn override_criteria(&self) -> OverrideCriteriaFn {
671+
self.override_criteria()
672+
}
673+
fn pinned_connection(&self) -> Option<&PinnedConnectionHandle> {
674+
self.pinned_connection()
675+
}
676+
fn name(&self) -> &CStr {
677+
self.name()
678+
}
679+
fn target(&self) -> OperationTarget {
680+
self.target()
681+
}
682+
#[cfg(feature = "opentelemetry")]
683+
type Otel = <Self as OperationWrapper>::Otel;
684+
}
685+
480686
fn should_redact_body(body: &RawDocumentBuf) -> bool {
481687
if let Some(Ok((command_name, _))) = body.into_iter().next() {
482688
HELLO_COMMAND_NAMES.contains(command_name.to_lowercase().as_str())

driver/src/operation/aggregate/change_stream.rs

Lines changed: 22 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,18 @@ use crate::{
44
common::{ChangeStreamData, WatchArgs},
55
event::ResumeToken,
66
},
7-
client::Retry,
87
cmap::{Command, RawCommandResponse, StreamDescription},
98
cursor::common::CursorSpecification,
109
error::Result,
11-
operation::{append_options, ExecutionContext, Operation, Retryability},
12-
options::{ChangeStreamOptions, ClientOptions, SelectionCriteria, WriteConcern},
10+
operation::{
11+
append_options,
12+
ExecutionContext,
13+
Operation,
14+
OperationImpl,
15+
OperationWrapper,
16+
Wrapper,
17+
},
18+
options::ChangeStreamOptions,
1319
};
1420

1521
use super::Aggregate;
@@ -43,12 +49,18 @@ impl ChangeStreamAggregate {
4349
}
4450
}
4551

46-
impl Operation for ChangeStreamAggregate {
52+
impl OperationWrapper for ChangeStreamAggregate {
53+
type Wrapped = Aggregate;
4754
type O = (CursorSpecification, ChangeStreamData);
55+
const ZERO_COPY: bool = true;
4856

49-
const NAME: &'static crate::bson_compat::CStr = Aggregate::NAME;
57+
fn wrapped(&self) -> &Self::Wrapped {
58+
&self.inner
59+
}
5060

51-
const ZERO_COPY: bool = true;
61+
fn wrapped_mut(&mut self) -> &mut Self::Wrapped {
62+
&mut self.inner
63+
}
5264

5365
fn build(&mut self, description: &StreamDescription) -> Result<Command> {
5466
if let Some(data) = &mut self.resume_data {
@@ -80,13 +92,6 @@ impl Operation for ChangeStreamAggregate {
8092
self.inner.build(description)
8193
}
8294

83-
fn extract_at_cluster_time(
84-
&self,
85-
response: &crate::bson::RawDocument,
86-
) -> Result<Option<crate::bson::Timestamp>> {
87-
self.inner.extract_at_cluster_time(response)
88-
}
89-
9095
fn handle_response<'a>(
9196
&'a self,
9297
response: std::borrow::Cow<'a, RawCommandResponse>,
@@ -133,57 +138,13 @@ impl Operation for ChangeStreamAggregate {
133138
.boxed()
134139
}
135140

136-
fn selection_criteria(&self) -> crate::operation::Feature<&SelectionCriteria> {
137-
self.inner.selection_criteria()
138-
}
139-
140-
fn write_concern(&self) -> crate::operation::Feature<&WriteConcern> {
141-
self.inner.write_concern()
142-
}
143-
144-
fn retryability(&self, options: &ClientOptions) -> Retryability {
145-
self.inner.retryability(options)
146-
}
147-
148-
fn is_backpressure_retryable(&self, options: &ClientOptions) -> bool {
149-
self.inner.is_backpressure_retryable(options)
150-
}
151-
152-
fn target(&self) -> crate::operation::OperationTarget {
153-
self.inner.target()
154-
}
155-
156-
fn handle_error(&self, error: crate::error::Error) -> Result<Self::O> {
157-
Err(error)
158-
}
159-
160-
fn read_concern(&self) -> crate::operation::Feature<&crate::options::ReadConcern> {
161-
self.inner.read_concern()
162-
}
163-
164-
fn supports_sessions(&self) -> bool {
165-
self.inner.supports_sessions()
166-
}
167-
168-
fn update_for_retry(&mut self, retry: Option<&Retry>) {
169-
self.inner.update_for_retry(retry);
170-
}
171-
172-
fn override_criteria(&self) -> crate::operation::OverrideCriteriaFn {
173-
self.inner.override_criteria()
174-
}
175-
176-
fn pinned_connection(&self) -> Option<&crate::cmap::conn::PinnedConnectionHandle> {
177-
self.inner.pinned_connection()
178-
}
179-
180-
fn name(&self) -> &crate::bson_compat::CStr {
181-
self.inner.name()
182-
}
183-
184141
#[cfg(feature = "opentelemetry")]
185142
type Otel = crate::otel::Witness<Self>;
186143
}
187144

145+
impl OperationImpl for ChangeStreamAggregate {
146+
type Kind = Wrapper;
147+
}
148+
188149
#[cfg(feature = "opentelemetry")]
189150
impl crate::otel::OtelInfoDefaults for ChangeStreamAggregate {}

0 commit comments

Comments
 (0)