Skip to main content

rootle_github/client/
refs.rs

1//! Branch/tag discovery.
2
3use super::{API, GitHubClient};
4use crate::types::RepoMeta;
5use rootle_provider::ProviderResult;
6
7impl GitHubClient {
8    /// Branches (first 100) + tags (first 100); the repo's default
9    /// branch is marked. Refs past the cap are out of scope for a
10    /// switcher.
11    pub fn refs(&self, owner: &str, repo: &str) -> ProviderResult<rootle_provider::RepoRefs> {
12        #[derive(serde::Deserialize)]
13        struct BranchItem {
14            name: String,
15            commit: CommitRef,
16        }
17        #[derive(serde::Deserialize)]
18        struct CommitRef {
19            sha: String,
20        }
21        #[derive(serde::Deserialize)]
22        struct TagRef {
23            #[serde(rename = "ref")]
24            name: String, // "refs/tags/v1.0"
25            object: CommitRef,
26        }
27        let meta: RepoMeta = self.get(&format!("{API}/repos/{owner}/{repo}"))?;
28        let branches: Vec<BranchItem> =
29            self.get(&format!("{API}/repos/{owner}/{repo}/branches?per_page=100"))?;
30        let tags: Vec<TagRef> = self.get(&format!(
31            "{API}/repos/{owner}/{repo}/git/refs/tags?per_page=100"
32        ))?;
33        Ok(rootle_provider::RepoRefs {
34            branches: branches
35                .into_iter()
36                .map(|b| rootle_provider::RefInfo {
37                    is_default: b.name == meta.default_branch,
38                    name: b.name,
39                    sha: b.commit.sha,
40                })
41                .collect(),
42            tags: tags
43                .into_iter()
44                .map(|t| rootle_provider::RefInfo {
45                    name: t.name.trim_start_matches("refs/tags/").to_string(),
46                    sha: t.object.sha,
47                    is_default: false,
48                })
49                .collect(),
50        })
51    }
52}