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}