sourcehut.rs

  1use url::Url;
  2
  3use crate::{
  4    BuildCommitPermalinkParams, BuildPermalinkParams, GitHostingProvider, ParsedGitRemote,
  5};
  6
  7pub struct Sourcehut;
  8
  9impl GitHostingProvider for Sourcehut {
 10    fn name(&self) -> String {
 11        "Gitee".to_string()
 12    }
 13
 14    fn base_url(&self) -> Url {
 15        Url::parse("https://git.sr.ht").unwrap()
 16    }
 17
 18    fn supports_avatars(&self) -> bool {
 19        false
 20    }
 21
 22    fn format_line_number(&self, line: u32) -> String {
 23        format!("L{line}")
 24    }
 25
 26    fn format_line_numbers(&self, start_line: u32, end_line: u32) -> String {
 27        format!("L{start_line}-{end_line}")
 28    }
 29
 30    fn parse_remote_url<'a>(&self, url: &'a str) -> Option<ParsedGitRemote<'a>> {
 31        if url.starts_with("git@git.sr.ht:") || url.starts_with("https://git.sr.ht/") {
 32            // sourcehut indicates a repo with '.git' suffix as a separate repo.
 33            // For example, "git@git.sr.ht:~username/repo" and "git@git.sr.ht:~username/repo.git"
 34            // are two distinct repositories.
 35            let repo_with_owner = url
 36                .trim_start_matches("git@git.sr.ht:~")
 37                .trim_start_matches("https://git.sr.ht/~");
 38
 39            let (owner, repo) = repo_with_owner.split_once('/')?;
 40
 41            return Some(ParsedGitRemote { owner, repo });
 42        }
 43
 44        None
 45    }
 46
 47    fn build_commit_permalink(
 48        &self,
 49        remote: &ParsedGitRemote,
 50        params: BuildCommitPermalinkParams,
 51    ) -> Url {
 52        let BuildCommitPermalinkParams { sha } = params;
 53        let ParsedGitRemote { owner, repo } = remote;
 54
 55        self.base_url()
 56            .join(&format!("~{owner}/{repo}/commit/{sha}"))
 57            .unwrap()
 58    }
 59
 60    fn build_permalink(&self, remote: ParsedGitRemote, params: BuildPermalinkParams) -> Url {
 61        let ParsedGitRemote { owner, repo } = remote;
 62        let BuildPermalinkParams {
 63            sha,
 64            path,
 65            selection,
 66        } = params;
 67
 68        let mut permalink = self
 69            .base_url()
 70            .join(&format!("~{owner}/{repo}/tree/{sha}/item/{path}"))
 71            .unwrap();
 72        permalink.set_fragment(
 73            selection
 74                .map(|selection| self.line_fragment(&selection))
 75                .as_deref(),
 76        );
 77        permalink
 78    }
 79}
 80
 81#[cfg(test)]
 82mod tests {
 83    use super::*;
 84
 85    #[test]
 86    fn test_build_sourcehut_permalink_from_ssh_url() {
 87        let remote = ParsedGitRemote {
 88            owner: "rajveermalviya",
 89            repo: "zed",
 90        };
 91        let permalink = Sourcehut.build_permalink(
 92            remote,
 93            BuildPermalinkParams {
 94                sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
 95                path: "crates/editor/src/git/permalink.rs",
 96                selection: None,
 97            },
 98        );
 99
100        let expected_url = "https://git.sr.ht/~rajveermalviya/zed/tree/faa6f979be417239b2e070dbbf6392b909224e0b/item/crates/editor/src/git/permalink.rs";
101        assert_eq!(permalink.to_string(), expected_url.to_string())
102    }
103
104    #[test]
105    fn test_build_sourcehut_permalink_from_ssh_url_with_git_prefix() {
106        let remote = ParsedGitRemote {
107            owner: "rajveermalviya",
108            repo: "zed.git",
109        };
110        let permalink = Sourcehut.build_permalink(
111            remote,
112            BuildPermalinkParams {
113                sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
114                path: "crates/editor/src/git/permalink.rs",
115                selection: None,
116            },
117        );
118
119        let expected_url = "https://git.sr.ht/~rajveermalviya/zed.git/tree/faa6f979be417239b2e070dbbf6392b909224e0b/item/crates/editor/src/git/permalink.rs";
120        assert_eq!(permalink.to_string(), expected_url.to_string())
121    }
122
123    #[test]
124    fn test_build_sourcehut_permalink_from_ssh_url_single_line_selection() {
125        let remote = ParsedGitRemote {
126            owner: "rajveermalviya",
127            repo: "zed",
128        };
129        let permalink = Sourcehut.build_permalink(
130            remote,
131            BuildPermalinkParams {
132                sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
133                path: "crates/editor/src/git/permalink.rs",
134                selection: Some(6..6),
135            },
136        );
137
138        let expected_url = "https://git.sr.ht/~rajveermalviya/zed/tree/faa6f979be417239b2e070dbbf6392b909224e0b/item/crates/editor/src/git/permalink.rs#L7";
139        assert_eq!(permalink.to_string(), expected_url.to_string())
140    }
141
142    #[test]
143    fn test_build_sourcehut_permalink_from_ssh_url_multi_line_selection() {
144        let remote = ParsedGitRemote {
145            owner: "rajveermalviya",
146            repo: "zed",
147        };
148        let permalink = Sourcehut.build_permalink(
149            remote,
150            BuildPermalinkParams {
151                sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
152                path: "crates/editor/src/git/permalink.rs",
153                selection: Some(23..47),
154            },
155        );
156
157        let expected_url = "https://git.sr.ht/~rajveermalviya/zed/tree/faa6f979be417239b2e070dbbf6392b909224e0b/item/crates/editor/src/git/permalink.rs#L24-48";
158        assert_eq!(permalink.to_string(), expected_url.to_string())
159    }
160
161    #[test]
162    fn test_build_sourcehut_permalink_from_https_url() {
163        let remote = ParsedGitRemote {
164            owner: "rajveermalviya",
165            repo: "zed",
166        };
167        let permalink = Sourcehut.build_permalink(
168            remote,
169            BuildPermalinkParams {
170                sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
171                path: "crates/zed/src/main.rs",
172                selection: None,
173            },
174        );
175
176        let expected_url = "https://git.sr.ht/~rajveermalviya/zed/tree/faa6f979be417239b2e070dbbf6392b909224e0b/item/crates/zed/src/main.rs";
177        assert_eq!(permalink.to_string(), expected_url.to_string())
178    }
179
180    #[test]
181    fn test_build_sourcehut_permalink_from_https_url_single_line_selection() {
182        let remote = ParsedGitRemote {
183            owner: "rajveermalviya",
184            repo: "zed",
185        };
186        let permalink = Sourcehut.build_permalink(
187            remote,
188            BuildPermalinkParams {
189                sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
190                path: "crates/zed/src/main.rs",
191                selection: Some(6..6),
192            },
193        );
194
195        let expected_url = "https://git.sr.ht/~rajveermalviya/zed/tree/faa6f979be417239b2e070dbbf6392b909224e0b/item/crates/zed/src/main.rs#L7";
196        assert_eq!(permalink.to_string(), expected_url.to_string())
197    }
198
199    #[test]
200    fn test_build_sourcehut_permalink_from_https_url_multi_line_selection() {
201        let remote = ParsedGitRemote {
202            owner: "rajveermalviya",
203            repo: "zed",
204        };
205        let permalink = Sourcehut.build_permalink(
206            remote,
207            BuildPermalinkParams {
208                sha: "faa6f979be417239b2e070dbbf6392b909224e0b",
209                path: "crates/zed/src/main.rs",
210                selection: Some(23..47),
211            },
212        );
213
214        let expected_url = "https://git.sr.ht/~rajveermalviya/zed/tree/faa6f979be417239b2e070dbbf6392b909224e0b/item/crates/zed/src/main.rs#L24-48";
215        assert_eq!(permalink.to_string(), expected_url.to_string())
216    }
217}