Skip to main content

rocketmq_client_rust/producer/
capability.rs

1// Copyright 2023 The RocketMQ Rust Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Focused Producer capabilities.
16//!
17//! Public consumers depend on lifecycle, send, transaction, request/reply,
18//! recall, query, or topic-administration behavior without observing the
19//! internal producer backend.
20
21use std::any::Any;
22use std::collections::HashMap;
23
24use cheetah_string::CheetahString;
25use rocketmq_model::common::message::message_ext::MessageExt;
26use rocketmq_model::common::message::message_queue::MessageQueue;
27use rocketmq_model::common::message::MessageTrait;
28
29use super::producer_backend::ProducerBackend;
30use super::request_callback::RequestCallbackFn;
31use super::send_callback::ArcSendCallback;
32use super::DefaultMQProducer;
33use super::SendResult;
34use super::TransactionMQProducer;
35use super::TransactionSendResult;
36use crate::base::query_result::QueryResult;
37
38/// Destination selected before entering the send capability.
39#[derive(Clone, Debug, Eq, PartialEq)]
40pub enum SendDestination {
41    /// Use the producer's normal routing strategy.
42    Automatic,
43    /// Send to one explicit queue.
44    Queue(MessageQueue),
45}
46
47/// Completion contract for one send request.
48#[derive(Clone, Copy, Debug, Eq, PartialEq)]
49pub enum SendMode {
50    /// Wait for and return the broker send result.
51    AwaitResult,
52    /// Submit a one-way send without a broker result.
53    Oneway,
54}
55
56/// One message send with destination, completion mode, and deadline policy.
57pub struct SendRequest<M> {
58    pub message: M,
59    pub destination: SendDestination,
60    pub mode: SendMode,
61    /// Timeout in milliseconds, or the configured producer default.
62    pub timeout_millis: Option<u64>,
63}
64
65/// Batch send with destination and deadline policy.
66pub struct BatchSendRequest<M> {
67    pub messages: Vec<M>,
68    pub destination: SendDestination,
69    /// Timeout in milliseconds, or the configured producer default.
70    pub timeout_millis: Option<u64>,
71}
72
73/// Callback-based send with an optional explicit queue.
74pub struct SendCallbackRequest<M> {
75    pub message: M,
76    pub destination: SendDestination,
77    pub timeout_millis: Option<u64>,
78    pub callback: ArcSendCallback,
79}
80
81/// Selector-based send without duplicating destination overloads.
82pub struct SelectedSendRequest<M, S, T> {
83    pub message: M,
84    pub selector: S,
85    pub argument: T,
86    pub mode: SendMode,
87    pub timeout_millis: Option<u64>,
88}
89
90/// Callback-based selector send.
91pub struct SelectedSendCallbackRequest<M, S, T> {
92    pub message: M,
93    pub selector: S,
94    pub argument: T,
95    pub timeout_millis: Option<u64>,
96    pub callback: ArcSendCallback,
97}
98
99/// Callback-based batch send with an optional explicit queue.
100pub struct BatchSendCallbackRequest<M> {
101    pub messages: Vec<M>,
102    pub destination: SendDestination,
103    pub timeout_millis: Option<u64>,
104    pub callback: ArcSendCallback,
105}
106
107/// Recall a previously sent message.
108pub struct RecallRequest {
109    pub topic: CheetahString,
110    pub recall_handle: CheetahString,
111}
112
113/// Request/reply invocation with an optional explicit queue.
114pub struct RequestReplyRequest<M> {
115    pub message: M,
116    pub destination: SendDestination,
117    pub timeout_millis: u64,
118}
119
120/// Callback-based request/reply invocation.
121pub struct RequestReplyCallbackRequest<M> {
122    pub message: M,
123    pub destination: SendDestination,
124    pub timeout_millis: u64,
125    pub callback: RequestCallbackFn,
126}
127
128/// Selector-based request/reply invocation.
129pub struct SelectedRequestReplyRequest<M, S, T> {
130    pub message: M,
131    pub selector: S,
132    pub argument: T,
133    pub timeout_millis: u64,
134}
135
136/// Callback-based selector request/reply invocation.
137pub struct SelectedRequestReplyCallbackRequest<M, S, T> {
138    pub message: M,
139    pub selector: S,
140    pub argument: T,
141    pub timeout_millis: u64,
142    pub callback: RequestCallbackFn,
143}
144
145/// Transactional send input.
146pub struct TransactionSendRequest<M, T> {
147    pub message: M,
148    pub argument: Option<T>,
149}
150
151/// Producer-side metadata query.
152pub enum ProducerQueryRequest {
153    FetchPublishQueues {
154        topic: String,
155    },
156    SearchOffset {
157        queue: MessageQueue,
158        timestamp: u64,
159    },
160    MaxOffset {
161        queue: MessageQueue,
162    },
163    MinOffset {
164        queue: MessageQueue,
165    },
166    EarliestStoreTime {
167        queue: MessageQueue,
168    },
169    QueryMessages {
170        topic: String,
171        key: String,
172        max_count: i32,
173        begin_timestamp: u64,
174        end_timestamp: u64,
175    },
176    ViewMessage {
177        topic: String,
178        message_id: String,
179    },
180}
181
182/// Closed result set corresponding to [`ProducerQueryRequest`].
183pub enum ProducerQueryResponse {
184    Queues(Vec<MessageQueue>),
185    Offset(i64),
186    Timestamp(i64),
187    Query(QueryResult),
188    Message(Box<MessageExt>),
189}
190
191/// Topic creation input shared by both legacy overloads.
192pub struct TopicCreateRequest {
193    pub key: String,
194    pub topic: String,
195    pub queue_count: i32,
196    pub system_flag: Option<i32>,
197    pub attributes: HashMap<String, String>,
198}
199
200/// Producer startup and shutdown capability.
201#[allow(async_fn_in_trait)]
202pub trait ProducerLifecycle {
203    /// Starts the producer.
204    ///
205    /// # Errors
206    ///
207    /// Returns the existing typed client error when startup fails.
208    async fn start_producer(&mut self) -> crate::ClientResult<()>;
209
210    /// Shuts down producer-owned work.
211    async fn shutdown_producer(&mut self);
212}
213
214/// Normal send, batch-send, and one-way capability.
215#[allow(async_fn_in_trait)]
216pub trait MessageSend {
217    /// Sends one message using a closed request contract.
218    ///
219    /// # Errors
220    ///
221    /// Preserves the error returned by the corresponding legacy operation.
222    async fn send_message<M>(&mut self, request: SendRequest<M>) -> crate::ClientResult<Option<SendResult>>
223    where
224        M: MessageTrait + Send + Sync;
225
226    /// Sends a batch using a closed request contract.
227    ///
228    /// # Errors
229    ///
230    /// Preserves the error returned by the corresponding legacy operation.
231    async fn send_message_batch<M>(&mut self, request: BatchSendRequest<M>) -> crate::ClientResult<SendResult>
232    where
233        M: MessageTrait + Send + Sync;
234
235    /// Sends one message and reports completion through the supplied callback.
236    ///
237    /// # Errors
238    ///
239    /// Preserves the corresponding legacy validation and submission errors.
240    async fn send_message_with_callback<M>(&mut self, request: SendCallbackRequest<M>) -> crate::ClientResult<()>
241    where
242        M: MessageTrait + Send + Sync;
243
244    /// Sends one message using a queue selector.
245    ///
246    /// # Errors
247    ///
248    /// Preserves selector, routing, and send errors from the legacy operation.
249    async fn send_selected<M, S, T>(
250        &mut self,
251        request: SelectedSendRequest<M, S, T>,
252    ) -> crate::ClientResult<Option<SendResult>>
253    where
254        M: MessageTrait + Send + Sync,
255        S: Fn(&[MessageQueue], &M, &T) -> Option<MessageQueue> + Send + Sync + 'static,
256        T: Send + Sync + 'static;
257
258    /// Sends one selected message and reports completion through a callback.
259    ///
260    /// # Errors
261    ///
262    /// Preserves selector, routing, and submission errors.
263    async fn send_selected_with_callback<M, S, T>(
264        &mut self,
265        request: SelectedSendCallbackRequest<M, S, T>,
266    ) -> crate::ClientResult<()>
267    where
268        M: MessageTrait + Send + Sync,
269        S: Fn(&[MessageQueue], &M, &T) -> Option<MessageQueue> + Send + Sync + 'static,
270        T: Send + Sync + 'static;
271
272    /// Sends a batch and reports completion through a callback.
273    ///
274    /// # Errors
275    ///
276    /// Preserves the corresponding legacy validation and submission errors.
277    async fn send_message_batch_with_callback<M>(
278        &mut self,
279        request: BatchSendCallbackRequest<M>,
280    ) -> crate::ClientResult<()>
281    where
282        M: MessageTrait + Send + Sync;
283}
284
285/// Message recall capability.
286#[allow(async_fn_in_trait)]
287pub trait MessageRecall {
288    /// Recalls one message.
289    ///
290    /// # Errors
291    ///
292    /// Preserves the existing recall validation or remoting error.
293    async fn recall(&mut self, request: RecallRequest) -> crate::ClientResult<String>;
294}
295
296/// Transactional send capability implemented only by transaction producers.
297#[allow(async_fn_in_trait)]
298pub trait TransactionSend {
299    /// Sends a prepared message and executes the configured transaction listener.
300    ///
301    /// # Errors
302    ///
303    /// Returns the existing transaction listener, send, or end-transaction error.
304    async fn send_transaction<M, T>(
305        &mut self,
306        request: TransactionSendRequest<M, T>,
307    ) -> crate::ClientResult<TransactionSendResult>
308    where
309        M: MessageTrait + Send + Sync,
310        T: Any + Send + Sync;
311}
312
313/// Request/reply capability.
314#[allow(async_fn_in_trait)]
315pub trait RequestReply {
316    /// Sends a request and waits for its correlated reply.
317    ///
318    /// # Errors
319    ///
320    /// Preserves the existing timeout, routing, and remoting errors.
321    async fn request_reply<M>(
322        &mut self,
323        request: RequestReplyRequest<M>,
324    ) -> crate::ClientResult<Box<dyn MessageTrait + Send>>
325    where
326        M: MessageTrait + Send + Sync;
327
328    /// Sends a request and reports its correlated reply through a callback.
329    ///
330    /// # Errors
331    ///
332    /// Preserves timeout, routing, and submission errors.
333    async fn request_reply_with_callback<M>(
334        &mut self,
335        request: RequestReplyCallbackRequest<M>,
336    ) -> crate::ClientResult<()>
337    where
338        M: MessageTrait + Send + Sync;
339
340    /// Sends a selector-routed request and waits for its reply.
341    ///
342    /// # Errors
343    ///
344    /// Preserves selector, timeout, routing, and remoting errors.
345    async fn request_reply_selected<M, S, T>(
346        &mut self,
347        request: SelectedRequestReplyRequest<M, S, T>,
348    ) -> crate::ClientResult<Box<dyn MessageTrait + Send>>
349    where
350        M: MessageTrait + Send + Sync,
351        S: Fn(&[MessageQueue], &M, &T) -> Option<MessageQueue> + Send + Sync + 'static,
352        T: Send + Sync + 'static;
353
354    /// Sends a selector-routed request and reports its reply through a callback.
355    ///
356    /// # Errors
357    ///
358    /// Preserves selector, timeout, routing, and submission errors.
359    async fn request_reply_selected_with_callback<M, S, T>(
360        &mut self,
361        request: SelectedRequestReplyCallbackRequest<M, S, T>,
362    ) -> crate::ClientResult<()>
363    where
364        M: MessageTrait + Send + Sync,
365        S: Fn(&[MessageQueue], &M, &T) -> Option<MessageQueue> + Send + Sync + 'static,
366        T: Send + Sync + 'static;
367}
368
369/// Producer metadata and message-query capability.
370#[allow(async_fn_in_trait)]
371pub trait MessageQuery {
372    /// Executes one producer query.
373    ///
374    /// # Errors
375    ///
376    /// Preserves the error behavior of the mapped legacy query.
377    async fn query(&mut self, request: ProducerQueryRequest) -> crate::ClientResult<ProducerQueryResponse>;
378}
379
380/// Producer topic-administration capability.
381#[allow(async_fn_in_trait)]
382pub trait ProducerTopicAdmin {
383    /// Creates a topic through the producer's existing admin facade.
384    ///
385    /// # Errors
386    ///
387    /// Preserves validation and broker errors from the legacy operation.
388    async fn create_topic_request(&mut self, request: TopicCreateRequest) -> crate::ClientResult<()>;
389}
390
391impl ProducerLifecycle for DefaultMQProducer {
392    async fn start_producer(&mut self) -> crate::ClientResult<()> {
393        <Self as ProducerBackend>::start(self).await
394    }
395
396    async fn shutdown_producer(&mut self) {
397        <Self as ProducerBackend>::shutdown(self).await;
398    }
399}
400
401impl MessageSend for DefaultMQProducer {
402    async fn send_message<M>(&mut self, request: SendRequest<M>) -> crate::ClientResult<Option<SendResult>>
403    where
404        M: MessageTrait + Send + Sync,
405    {
406        match (request.destination, request.mode, request.timeout_millis) {
407            (SendDestination::Automatic, SendMode::AwaitResult, None) => {
408                <Self as ProducerBackend>::send(self, request.message).await
409            }
410            (SendDestination::Automatic, SendMode::AwaitResult, Some(timeout)) => {
411                <Self as ProducerBackend>::send_with_timeout(self, request.message, timeout).await
412            }
413            (SendDestination::Queue(queue), SendMode::AwaitResult, None) => {
414                <Self as ProducerBackend>::send_to_queue(self, request.message, queue).await
415            }
416            (SendDestination::Queue(queue), SendMode::AwaitResult, Some(timeout)) => {
417                <Self as ProducerBackend>::send_to_queue_with_timeout(self, request.message, queue, timeout).await
418            }
419            (SendDestination::Automatic, SendMode::Oneway, _) => {
420                <Self as ProducerBackend>::send_oneway(self, request.message).await?;
421                Ok(None)
422            }
423            (SendDestination::Queue(queue), SendMode::Oneway, _) => {
424                <Self as ProducerBackend>::send_oneway_to_queue(self, request.message, queue).await?;
425                Ok(None)
426            }
427        }
428    }
429
430    async fn send_message_batch<M>(&mut self, request: BatchSendRequest<M>) -> crate::ClientResult<SendResult>
431    where
432        M: MessageTrait + Send + Sync,
433    {
434        match (request.destination, request.timeout_millis) {
435            (SendDestination::Automatic, None) => <Self as ProducerBackend>::send_batch(self, request.messages).await,
436            (SendDestination::Automatic, Some(timeout)) => {
437                <Self as ProducerBackend>::send_batch_with_timeout(self, request.messages, timeout).await
438            }
439            (SendDestination::Queue(queue), None) => {
440                <Self as ProducerBackend>::send_batch_to_queue(self, request.messages, queue).await
441            }
442            (SendDestination::Queue(queue), Some(timeout)) => {
443                <Self as ProducerBackend>::send_batch_to_queue_with_timeout(self, request.messages, queue, timeout)
444                    .await
445            }
446        }
447    }
448
449    async fn send_message_with_callback<M>(&mut self, request: SendCallbackRequest<M>) -> crate::ClientResult<()>
450    where
451        M: MessageTrait + Send + Sync,
452    {
453        let callback = request.callback;
454        let callback_fn = move |result: Option<&SendResult>, error: Option<&crate::ClientError>| {
455            if let Some(result) = result {
456                callback.on_success(result);
457            } else if let Some(error) = error {
458                callback.on_exception(error);
459            }
460        };
461        match (request.destination, request.timeout_millis) {
462            (SendDestination::Automatic, None) => {
463                <Self as ProducerBackend>::send_with_callback(self, request.message, callback_fn).await
464            }
465            (SendDestination::Automatic, Some(timeout)) => {
466                <Self as ProducerBackend>::send_with_callback_timeout(self, request.message, callback_fn, timeout).await
467            }
468            (SendDestination::Queue(queue), None) => {
469                <Self as ProducerBackend>::send_to_queue_with_callback(self, request.message, queue, callback_fn).await
470            }
471            (SendDestination::Queue(queue), Some(timeout)) => {
472                <Self as ProducerBackend>::send_to_queue_with_callback_timeout(
473                    self,
474                    request.message,
475                    queue,
476                    callback_fn,
477                    timeout,
478                )
479                .await
480            }
481        }
482    }
483
484    async fn send_selected<M, S, T>(
485        &mut self,
486        request: SelectedSendRequest<M, S, T>,
487    ) -> crate::ClientResult<Option<SendResult>>
488    where
489        M: MessageTrait + Send + Sync,
490        S: Fn(&[MessageQueue], &M, &T) -> Option<MessageQueue> + Send + Sync + 'static,
491        T: Send + Sync + 'static,
492    {
493        match (request.mode, request.timeout_millis) {
494            (SendMode::AwaitResult, None) => {
495                <Self as ProducerBackend>::send_with_selector(self, request.message, request.selector, request.argument)
496                    .await
497            }
498            (SendMode::AwaitResult, Some(timeout)) => {
499                <Self as ProducerBackend>::send_with_selector_timeout(
500                    self,
501                    request.message,
502                    request.selector,
503                    request.argument,
504                    timeout,
505                )
506                .await
507            }
508            (SendMode::Oneway, _) => {
509                <Self as ProducerBackend>::send_oneway_with_selector(
510                    self,
511                    request.message,
512                    request.selector,
513                    request.argument,
514                )
515                .await?;
516                Ok(None)
517            }
518        }
519    }
520
521    async fn send_selected_with_callback<M, S, T>(
522        &mut self,
523        request: SelectedSendCallbackRequest<M, S, T>,
524    ) -> crate::ClientResult<()>
525    where
526        M: MessageTrait + Send + Sync,
527        S: Fn(&[MessageQueue], &M, &T) -> Option<MessageQueue> + Send + Sync + 'static,
528        T: Send + Sync + 'static,
529    {
530        match request.timeout_millis {
531            Some(timeout) => {
532                <Self as ProducerBackend>::send_with_selector_callback_timeout(
533                    self,
534                    request.message,
535                    request.selector,
536                    request.argument,
537                    Some(request.callback),
538                    timeout,
539                )
540                .await
541            }
542            None => {
543                <Self as ProducerBackend>::send_with_selector_callback(
544                    self,
545                    request.message,
546                    request.selector,
547                    request.argument,
548                    Some(request.callback),
549                )
550                .await
551            }
552        }
553    }
554
555    async fn send_message_batch_with_callback<M>(
556        &mut self,
557        request: BatchSendCallbackRequest<M>,
558    ) -> crate::ClientResult<()>
559    where
560        M: MessageTrait + Send + Sync,
561    {
562        let callback = request.callback;
563        let callback_fn = move |result: Option<&SendResult>, error: Option<&crate::ClientError>| {
564            if let Some(result) = result {
565                callback.on_success(result);
566            } else if let Some(error) = error {
567                callback.on_exception(error);
568            }
569        };
570        match (request.destination, request.timeout_millis) {
571            (SendDestination::Automatic, None) => {
572                <Self as ProducerBackend>::send_batch_with_callback(self, request.messages, callback_fn).await
573            }
574            (SendDestination::Automatic, Some(timeout)) => {
575                <Self as ProducerBackend>::send_batch_with_callback_timeout(
576                    self,
577                    request.messages,
578                    callback_fn,
579                    timeout,
580                )
581                .await
582            }
583            (SendDestination::Queue(queue), None) => {
584                <Self as ProducerBackend>::send_batch_to_queue_with_callback(self, request.messages, queue, callback_fn)
585                    .await
586            }
587            (SendDestination::Queue(queue), Some(timeout)) => {
588                <Self as ProducerBackend>::send_batch_to_queue_with_callback_timeout(
589                    self,
590                    request.messages,
591                    queue,
592                    callback_fn,
593                    timeout,
594                )
595                .await
596            }
597        }
598    }
599}
600
601impl MessageRecall for DefaultMQProducer {
602    async fn recall(&mut self, request: RecallRequest) -> crate::ClientResult<String> {
603        <Self as ProducerBackend>::recall_message(self, request.topic, request.recall_handle).await
604    }
605}
606
607impl RequestReply for DefaultMQProducer {
608    async fn request_reply<M>(
609        &mut self,
610        request: RequestReplyRequest<M>,
611    ) -> crate::ClientResult<Box<dyn MessageTrait + Send>>
612    where
613        M: MessageTrait + Send + Sync,
614    {
615        match request.destination {
616            SendDestination::Automatic => {
617                <Self as ProducerBackend>::request(self, request.message, request.timeout_millis).await
618            }
619            SendDestination::Queue(queue) => {
620                <Self as ProducerBackend>::request_to_queue(self, request.message, queue, request.timeout_millis).await
621            }
622        }
623    }
624
625    async fn request_reply_with_callback<M>(
626        &mut self,
627        request: RequestReplyCallbackRequest<M>,
628    ) -> crate::ClientResult<()>
629    where
630        M: MessageTrait + Send + Sync,
631    {
632        let callback = request.callback;
633        let callback_fn = move |response: Option<&dyn MessageTrait>, error: Option<&crate::ClientError>| {
634            callback(response, error);
635        };
636        match request.destination {
637            SendDestination::Automatic => {
638                <Self as ProducerBackend>::request_with_callback(
639                    self,
640                    request.message,
641                    callback_fn,
642                    request.timeout_millis,
643                )
644                .await
645            }
646            SendDestination::Queue(queue) => {
647                <Self as ProducerBackend>::request_to_queue_with_callback(
648                    self,
649                    request.message,
650                    queue,
651                    callback_fn,
652                    request.timeout_millis,
653                )
654                .await
655            }
656        }
657    }
658
659    async fn request_reply_selected<M, S, T>(
660        &mut self,
661        request: SelectedRequestReplyRequest<M, S, T>,
662    ) -> crate::ClientResult<Box<dyn MessageTrait + Send>>
663    where
664        M: MessageTrait + Send + Sync,
665        S: Fn(&[MessageQueue], &M, &T) -> Option<MessageQueue> + Send + Sync + 'static,
666        T: Send + Sync + 'static,
667    {
668        <Self as ProducerBackend>::request_with_selector(
669            self,
670            request.message,
671            request.selector,
672            request.argument,
673            request.timeout_millis,
674        )
675        .await
676    }
677
678    async fn request_reply_selected_with_callback<M, S, T>(
679        &mut self,
680        request: SelectedRequestReplyCallbackRequest<M, S, T>,
681    ) -> crate::ClientResult<()>
682    where
683        M: MessageTrait + Send + Sync,
684        S: Fn(&[MessageQueue], &M, &T) -> Option<MessageQueue> + Send + Sync + 'static,
685        T: Send + Sync + 'static,
686    {
687        let callback = request.callback;
688        <Self as ProducerBackend>::request_with_selector_callback(
689            self,
690            request.message,
691            request.selector,
692            request.argument,
693            move |response, error| callback(response, error),
694            request.timeout_millis,
695        )
696        .await
697    }
698}
699
700impl MessageQuery for DefaultMQProducer {
701    async fn query(&mut self, request: ProducerQueryRequest) -> crate::ClientResult<ProducerQueryResponse> {
702        let response = match request {
703            ProducerQueryRequest::FetchPublishQueues { topic } => ProducerQueryResponse::Queues(
704                <Self as ProducerBackend>::fetch_publish_message_queues(self, &topic).await?,
705            ),
706            ProducerQueryRequest::SearchOffset { queue, timestamp } => {
707                ProducerQueryResponse::Offset(<Self as ProducerBackend>::search_offset(self, &queue, timestamp).await?)
708            }
709            ProducerQueryRequest::MaxOffset { queue } => {
710                ProducerQueryResponse::Offset(<Self as ProducerBackend>::max_offset(self, &queue).await?)
711            }
712            ProducerQueryRequest::MinOffset { queue } => {
713                ProducerQueryResponse::Offset(<Self as ProducerBackend>::min_offset(self, &queue).await?)
714            }
715            ProducerQueryRequest::EarliestStoreTime { queue } => ProducerQueryResponse::Timestamp(
716                <Self as ProducerBackend>::earliest_msg_store_time(self, &queue).await?,
717            ),
718            ProducerQueryRequest::QueryMessages {
719                topic,
720                key,
721                max_count,
722                begin_timestamp,
723                end_timestamp,
724            } => ProducerQueryResponse::Query(
725                <Self as ProducerBackend>::query_message(self, &topic, &key, max_count, begin_timestamp, end_timestamp)
726                    .await?,
727            ),
728            ProducerQueryRequest::ViewMessage { topic, message_id } => ProducerQueryResponse::Message(Box::new(
729                <Self as ProducerBackend>::view_message(self, &topic, &message_id).await?,
730            )),
731        };
732        Ok(response)
733    }
734}
735
736impl ProducerTopicAdmin for DefaultMQProducer {
737    async fn create_topic_request(&mut self, request: TopicCreateRequest) -> crate::ClientResult<()> {
738        match request.system_flag {
739            Some(system_flag) => {
740                <Self as ProducerBackend>::create_topic_with_flag(
741                    self,
742                    &request.key,
743                    &request.topic,
744                    request.queue_count,
745                    system_flag,
746                    request.attributes,
747                )
748                .await
749            }
750            None => {
751                <Self as ProducerBackend>::create_topic(
752                    self,
753                    &request.key,
754                    &request.topic,
755                    request.queue_count,
756                    request.attributes,
757                )
758                .await
759            }
760        }
761    }
762}
763
764impl ProducerLifecycle for TransactionMQProducer {
765    async fn start_producer(&mut self) -> crate::ClientResult<()> {
766        <Self as ProducerBackend>::start(self).await
767    }
768
769    async fn shutdown_producer(&mut self) {
770        <Self as ProducerBackend>::shutdown(self).await;
771    }
772}
773
774impl MessageSend for TransactionMQProducer {
775    async fn send_message<M>(&mut self, request: SendRequest<M>) -> crate::ClientResult<Option<SendResult>>
776    where
777        M: MessageTrait + Send + Sync,
778    {
779        self.default_producer_mut().send_message(request).await
780    }
781
782    async fn send_message_batch<M>(&mut self, request: BatchSendRequest<M>) -> crate::ClientResult<SendResult>
783    where
784        M: MessageTrait + Send + Sync,
785    {
786        self.default_producer_mut().send_message_batch(request).await
787    }
788
789    async fn send_message_with_callback<M>(&mut self, request: SendCallbackRequest<M>) -> crate::ClientResult<()>
790    where
791        M: MessageTrait + Send + Sync,
792    {
793        self.default_producer_mut().send_message_with_callback(request).await
794    }
795
796    async fn send_selected<M, S, T>(
797        &mut self,
798        request: SelectedSendRequest<M, S, T>,
799    ) -> crate::ClientResult<Option<SendResult>>
800    where
801        M: MessageTrait + Send + Sync,
802        S: Fn(&[MessageQueue], &M, &T) -> Option<MessageQueue> + Send + Sync + 'static,
803        T: Send + Sync + 'static,
804    {
805        self.default_producer_mut().send_selected(request).await
806    }
807
808    async fn send_selected_with_callback<M, S, T>(
809        &mut self,
810        request: SelectedSendCallbackRequest<M, S, T>,
811    ) -> crate::ClientResult<()>
812    where
813        M: MessageTrait + Send + Sync,
814        S: Fn(&[MessageQueue], &M, &T) -> Option<MessageQueue> + Send + Sync + 'static,
815        T: Send + Sync + 'static,
816    {
817        self.default_producer_mut().send_selected_with_callback(request).await
818    }
819
820    async fn send_message_batch_with_callback<M>(
821        &mut self,
822        request: BatchSendCallbackRequest<M>,
823    ) -> crate::ClientResult<()>
824    where
825        M: MessageTrait + Send + Sync,
826    {
827        self.default_producer_mut()
828            .send_message_batch_with_callback(request)
829            .await
830    }
831}
832
833impl MessageRecall for TransactionMQProducer {
834    async fn recall(&mut self, request: RecallRequest) -> crate::ClientResult<String> {
835        MessageRecall::recall(self.default_producer_mut(), request).await
836    }
837}
838
839impl RequestReply for TransactionMQProducer {
840    async fn request_reply<M>(
841        &mut self,
842        request: RequestReplyRequest<M>,
843    ) -> crate::ClientResult<Box<dyn MessageTrait + Send>>
844    where
845        M: MessageTrait + Send + Sync,
846    {
847        self.default_producer_mut().request_reply(request).await
848    }
849
850    async fn request_reply_with_callback<M>(
851        &mut self,
852        request: RequestReplyCallbackRequest<M>,
853    ) -> crate::ClientResult<()>
854    where
855        M: MessageTrait + Send + Sync,
856    {
857        self.default_producer_mut().request_reply_with_callback(request).await
858    }
859
860    async fn request_reply_selected<M, S, T>(
861        &mut self,
862        request: SelectedRequestReplyRequest<M, S, T>,
863    ) -> crate::ClientResult<Box<dyn MessageTrait + Send>>
864    where
865        M: MessageTrait + Send + Sync,
866        S: Fn(&[MessageQueue], &M, &T) -> Option<MessageQueue> + Send + Sync + 'static,
867        T: Send + Sync + 'static,
868    {
869        self.default_producer_mut().request_reply_selected(request).await
870    }
871
872    async fn request_reply_selected_with_callback<M, S, T>(
873        &mut self,
874        request: SelectedRequestReplyCallbackRequest<M, S, T>,
875    ) -> crate::ClientResult<()>
876    where
877        M: MessageTrait + Send + Sync,
878        S: Fn(&[MessageQueue], &M, &T) -> Option<MessageQueue> + Send + Sync + 'static,
879        T: Send + Sync + 'static,
880    {
881        self.default_producer_mut()
882            .request_reply_selected_with_callback(request)
883            .await
884    }
885}
886
887impl MessageQuery for TransactionMQProducer {
888    async fn query(&mut self, request: ProducerQueryRequest) -> crate::ClientResult<ProducerQueryResponse> {
889        MessageQuery::query(self.default_producer_mut(), request).await
890    }
891}
892
893impl ProducerTopicAdmin for TransactionMQProducer {
894    async fn create_topic_request(&mut self, request: TopicCreateRequest) -> crate::ClientResult<()> {
895        ProducerTopicAdmin::create_topic_request(self.default_producer_mut(), request).await
896    }
897}
898
899impl TransactionSend for TransactionMQProducer {
900    async fn send_transaction<M, T>(
901        &mut self,
902        request: TransactionSendRequest<M, T>,
903    ) -> crate::ClientResult<TransactionSendResult>
904    where
905        M: MessageTrait + Send + Sync,
906        T: Any + Send + Sync,
907    {
908        <Self as ProducerBackend>::send_message_in_transaction(self, request.message, request.argument).await
909    }
910}
911
912#[cfg(test)]
913mod tests {
914    use super::*;
915
916    fn assert_default_capabilities<T>()
917    where
918        T: ProducerLifecycle + MessageSend + MessageRecall + RequestReply + MessageQuery + ProducerTopicAdmin,
919    {
920    }
921
922    fn assert_transaction_capabilities<T>()
923    where
924        T: ProducerLifecycle + MessageSend + TransactionSend + RequestReply + MessageQuery + ProducerTopicAdmin,
925    {
926    }
927
928    #[test]
929    fn concrete_producers_expose_only_their_actual_capabilities() {
930        assert_default_capabilities::<DefaultMQProducer>();
931        assert_transaction_capabilities::<TransactionMQProducer>();
932    }
933}