adventure/
oneshot.rs

1use pin_utils::pin_mut;
2
3use crate::repeat::Repeat;
4use crate::request::{BaseRequest, Request};
5use crate::response::Response;
6
7/// A request that can be sent just once.
8pub trait OneshotRequest<C>: BaseRequest {
9    /// The type of corresponding responses of this request.
10    type Response: Response<Ok = Self::Ok, Error = Self::Error>;
11
12    /// Send this request to the given client, by consuming itself.
13    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/// An [`OneshotRequest`] adaptor for types that implements [`Request`].
24#[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}