git_assist/
host.rs

1#[cfg(feature = "github")]
2mod github;
3
4use std::str::FromStr;
5
6pub use self::github::*;
7
8use async_trait::async_trait;
9use git_url_parse::GitUrl;
10
11pub const GITHUB_HOST: &str = "github.com";
12
13pub enum SupportedHost {
14    Github,
15}
16
17impl TryFrom<&GitUrl> for SupportedHost {
18    type Error = anyhow::Error;
19
20    fn try_from(url: &GitUrl) -> Result<Self, Self::Error> {
21        match url.host.as_deref() {
22            Some(GITHUB_HOST) => {
23                if cfg!(feature = "github") {
24                    Ok(SupportedHost::Github)
25                } else {
26                    Err(anyhow::anyhow!("Github support is only available when compiled with `--features \"github\"`"))
27                }
28            }
29            Some(host) => Err(anyhow::anyhow!("Unsupported host: {host:?}")),
30            None => Err(anyhow::anyhow!("Unable to detect host: {url}")),
31        }
32    }
33}
34
35#[async_trait]
36pub trait GitHost {
37    async fn merged_pull_requests(
38        &self,
39        repository: &GitRepositoryUrl,
40    ) -> Result<Vec<GitPullRequest>, anyhow::Error>;
41}
42
43pub struct GitPullRequest {
44    pub identifier: String,
45    pub title: Option<String>,
46
47    pub base_sha: String,
48    pub merge_sha: String,
49}
50
51#[derive(Clone, Debug)]
52pub struct GitRepositoryUrl {
53    pub url_string: String,
54    pub parsed_url: GitUrl,
55}
56
57impl FromStr for GitRepositoryUrl {
58    type Err = anyhow::Error;
59
60    fn from_str(str: &str) -> Result<Self, Self::Err> {
61        let url_string = str.to_owned();
62        let parsed_url = GitUrl::parse(str).map_err(|report| anyhow::anyhow!("{report}"))?;
63
64        Ok(Self {
65            url_string,
66            parsed_url,
67        })
68    }
69}