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
use reqwest::{header::HeaderMap, StatusCode, Url, Version};

#[derive(Clone)]
pub struct GitHubResponse<ResponseData> {
  pub data: ResponseData,
  pub headers: HeaderMap,
  pub status: StatusCode,
  pub version: Version,
  pub content_length: Option<u64>,
  pub url: Url,
}

#[cfg(feature = "pagination")]
#[derive(Clone)]
pub struct GitHubPaginatedResponse<ResponseData> {
  pub data: ResponseData,
  pub headers: HeaderMap,
  pub status: StatusCode,
  pub version: Version,
  pub content_length: Option<u64>,
  pub url: Url,
  pub pages: octocrate_types::LinkedPages,
}

#[cfg(feature = "pagination")]
impl<ResponseData: serde::de::DeserializeOwned + IntoIterator>
  GitHubPaginatedResponse<ResponseData>
{
  pub fn paginate(self) -> octocrate_types::PaginatedData<ResponseData> {
    octocrate_types::PaginatedData {
      data: self.data,
      pages: self.pages,
    }
  }
}

#[cfg(feature = "pagination")]
impl<ResponseData: serde::de::DeserializeOwned + IntoIterator> From<GitHubResponse<ResponseData>>
  for GitHubPaginatedResponse<ResponseData>
{
  fn from(value: GitHubResponse<ResponseData>) -> Self {
    let GitHubResponse::<ResponseData> {
      data,
      headers,
      status,
      version,
      content_length,
      url,
    } = value;

    Self {
      data,
      headers: headers.clone(),
      status,
      version,
      content_length,
      url,
      pages: headers
        .get("link")
        .and_then(|header| header.to_str().ok())
        .map(From::from)
        .unwrap_or(Default::default()),
    }
  }
}