1use crate::client::{propagation_headers, HttpClient, NamedClient, PendingRequest};
4use sova_core::RequestId;
5use http::Method;
6use sova_core::Request;
7
8pub trait HttpExt {
10 fn http(&self) -> HttpBound<'_>;
11}
12
13impl HttpExt for Request {
14 fn http(&self) -> HttpBound<'_> {
15 HttpBound { req: self }
16 }
17}
18
19pub struct HttpBound<'a> {
21 req: &'a Request,
22}
23
24impl HttpBound<'_> {
25 fn client(&self) -> std::sync::Arc<HttpClient> {
26 self.req.state::<HttpClient>()
27 }
28
29 fn apply(&self, mut pending: PendingRequest) -> PendingRequest {
30 let _ = self.req.get::<RequestId>();
32 for (k, v) in propagation_headers(self.req).iter() {
33 pending.headers.insert(k.clone(), v.clone());
34 }
35 pending.with_budget(self.req.deadline_remaining())
36 }
37
38 pub fn get(&self, url: impl Into<String>) -> PendingRequest {
39 self.apply(self.client().get(url))
40 }
41
42 pub fn post(&self, url: impl Into<String>) -> PendingRequest {
43 self.apply(self.client().post(url))
44 }
45
46 pub fn put(&self, url: impl Into<String>) -> PendingRequest {
47 self.apply(self.client().put(url))
48 }
49
50 pub fn patch(&self, url: impl Into<String>) -> PendingRequest {
51 self.apply(self.client().patch(url))
52 }
53
54 pub fn delete(&self, url: impl Into<String>) -> PendingRequest {
55 self.apply(self.client().delete(url))
56 }
57
58 pub fn request(&self, method: Method, url: impl Into<String>) -> PendingRequest {
59 self.apply(self.client().request(method, url))
60 }
61
62 pub fn named(&self, name: &str) -> NamedBound<'_> {
63 NamedBound {
64 req: self.req,
65 named: self.client().named(name),
66 }
67 }
68}
69
70pub struct NamedBound<'a> {
71 req: &'a Request,
72 named: NamedClient,
73}
74
75impl NamedBound<'_> {
76 fn apply(&self, mut pending: PendingRequest) -> PendingRequest {
77 for (k, v) in propagation_headers(self.req).iter() {
78 pending.headers.insert(k.clone(), v.clone());
79 }
80 pending.with_budget(self.req.deadline_remaining())
81 }
82
83 pub fn get(&self, path: impl Into<String>) -> PendingRequest {
84 self.apply(self.named.get(path))
85 }
86
87 pub fn post(&self, path: impl Into<String>) -> PendingRequest {
88 self.apply(self.named.post(path))
89 }
90
91 pub fn put(&self, path: impl Into<String>) -> PendingRequest {
92 self.apply(self.named.put(path))
93 }
94
95 pub fn patch(&self, path: impl Into<String>) -> PendingRequest {
96 self.apply(self.named.patch(path))
97 }
98
99 pub fn delete(&self, path: impl Into<String>) -> PendingRequest {
100 self.apply(self.named.delete(path))
101 }
102}