1use pin_utils::pin_mut;
2
3use crate::repeat::Repeat;
4use crate::request::{BaseRequest, Request};
5use crate::response::Response;
6
7pub trait OneshotRequest<C>: BaseRequest {
9 type Response: Response<Ok = Self::Ok, Error = Self::Error>;
11
12 fn send_once(self, client: C) -> Self::Response;
14
15 fn repeat(self) -> Repeat<Self>
16 where
17 Self: Clone,
18 {
19 Repeat::from(self)
20 }
21}
22
23#[derive(Clone)]
25pub struct Oneshot<R> {
26 inner: R,
27}
28
29impl<R> From<R> for Oneshot<R> {
30 fn from(req: R) -> Self {
31 Oneshot { inner: req }
32 }
33}
34
35impl<R> BaseRequest for Oneshot<R>
36where
37 R: BaseRequest,
38{
39 type Ok = R::Ok;
40 type Error = R::Error;
41}
42
43impl<R, C> OneshotRequest<C> for Oneshot<R>
44where
45 R: Request<C>,
46{
47 type Response = R::Response;
48
49 fn send_once(self, client: C) -> Self::Response {
50 let inner = self.inner;
51 pin_mut!(inner);
52 inner.send(client)
53 }
54}
55
56#[cfg(feature = "backoff")]
57mod impl_retry {
58 use core::time::Duration;
59
60 use super::Oneshot;
61 use crate::retry::RetriableRequest;
62
63 impl<R> RetriableRequest for Oneshot<R>
64 where
65 R: RetriableRequest,
66 {
67 fn should_retry(&self, error: &Self::Error, next_interval: Duration) -> bool {
68 self.inner.should_retry(error, next_interval)
69 }
70 }
71}
72
73#[cfg(feature = "alloc")]
74mod feature_alloc {
75 use alloc::boxed::Box;
76
77 use super::*;
78
79 impl<R, C> OneshotRequest<C> for Box<R>
80 where
81 R: OneshotRequest<C>,
82 {
83 type Response = R::Response;
84 fn send_once(self, client: C) -> Self::Response {
85 let inner = *self;
86 inner.send_once(client)
87 }
88 }
89}