@@ -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.
302296pub ( 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
421446where
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+
480686fn 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 ( ) )
0 commit comments