binstalk_git_repo_api/gh_api_client/
repo_info.rs

1use std::{fmt, future::Future};
2
3use compact_str::CompactString;
4use serde::Deserialize;
5
6use super::{
7    common::{issue_graphql_query, issue_restful_api},
8    remote, GhApiError, GhRepo,
9};
10
11#[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize)]
12struct Owner {
13    login: CompactString,
14}
15
16#[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize)]
17pub struct RepoInfo {
18    owner: Owner,
19    name: CompactString,
20    private: bool,
21}
22
23impl fmt::Display for RepoInfo {
24    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25        write!(
26            f,
27            "RepoInfo {{ owner: {}, name: {}, is_private: {} }}",
28            self.owner.login, self.name, self.private
29        )
30    }
31}
32
33impl RepoInfo {
34    #[cfg(test)]
35    pub(crate) fn new(GhRepo { owner, repo }: GhRepo, private: bool) -> Self {
36        Self {
37            owner: Owner { login: owner },
38            name: repo,
39            private,
40        }
41    }
42    pub fn repo(&self) -> GhRepo {
43        GhRepo {
44            owner: self.owner.login.clone(),
45            repo: self.name.clone(),
46        }
47    }
48
49    pub fn is_private(&self) -> bool {
50        self.private
51    }
52}
53
54pub(super) fn fetch_repo_info_restful_api(
55    client: &remote::Client,
56    GhRepo { owner, repo }: &GhRepo,
57    auth_token: Option<&str>,
58) -> impl Future<Output = Result<Option<RepoInfo>, GhApiError>> + Send + 'static {
59    issue_restful_api(client, &["repos", owner, repo], auth_token)
60}
61
62#[derive(Debug, Deserialize)]
63struct GraphQLData {
64    repository: Option<RepoInfo>,
65}
66
67pub(super) fn fetch_repo_info_graphql_api(
68    client: &remote::Client,
69    GhRepo { owner, repo }: &GhRepo,
70    auth_token: &str,
71) -> impl Future<Output = Result<Option<RepoInfo>, GhApiError>> + Send + 'static {
72    let query = format!(
73        r#"
74query {{
75  repository(owner:"{owner}",name:"{repo}") {{
76    owner {{
77      login
78    }}
79    name
80    private: isPrivate
81  }}
82}}"#
83    );
84
85    let future = issue_graphql_query(client, query, auth_token);
86
87    async move {
88        let data: GraphQLData = future.await?;
89        Ok(data.repository)
90    }
91}