1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use crate::{api_config::SharedAPIConfig, request::Request};
use reqwest::Client;
use std::marker::PhantomData;

pub struct RequestBuilder<Body, Query, Response> {
  builder: Option<reqwest::RequestBuilder>,
  api_config: SharedAPIConfig,
  _body: PhantomData<Body>,
  _query: PhantomData<Query>,
  _response: PhantomData<Response>,
}

impl<Body, Query, Response> RequestBuilder<Body, Query, Response>
where
  Body: serde::Serialize,
  Query: serde::Serialize,
  Response: serde::de::DeserializeOwned,
{
  pub fn new(config: &SharedAPIConfig) -> Self {
    Self {
      builder: None,
      api_config: config.clone(),
      _body: PhantomData,
      _query: PhantomData,
      _response: PhantomData,
    }
  }

  pub fn get(mut self, url: impl Into<String>) -> Self {
    let url = format!("{}{}", self.api_config.base_url, url.into());
    let builder = Client::new().get(url);

    self.builder = Some(builder);

    self
  }

  pub fn post(mut self, url: impl Into<String>) -> Self {
    let url = format!("{}{}", self.api_config.base_url, url.into());
    let builder = Client::new().post(url);

    self.builder = Some(builder);

    self
  }

  pub fn put(mut self, url: impl Into<String>) -> Self {
    let url = format!("{}{}", self.api_config.base_url, url.into());
    let builder = Client::new().put(url);

    self.builder = Some(builder);

    self
  }

  pub fn patch(mut self, url: impl Into<String>) -> Self {
    let url = format!("{}{}", self.api_config.base_url, url.into());
    let builder = Client::new().patch(url);

    self.builder = Some(builder);

    self
  }

  pub fn delete(mut self, url: impl Into<String>) -> Self {
    let url = format!("{}{}", self.api_config.base_url, url.into());
    let builder = Client::new().delete(url);

    self.builder = Some(builder);

    self
  }

  pub fn build(self) -> Request<Body, Query, Response> {
    Request {
      builder: self.builder.expect("RequestBuilder is not configured"),
      api_config: self.api_config.clone(),
      _body: PhantomData,
      _query: PhantomData,
      _response: PhantomData,
    }
  }
}