1use crate::{
4 errors::GitMoverError,
5 utils::{check_ssh_access, Repo},
6};
7use serde::Deserialize;
8use std::pin::Pin;
9
10pub trait Platform: Sync + Send {
12 fn check_git_access(
14 &self,
15 ) -> Pin<Box<dyn std::future::Future<Output = Result<(), GitMoverError>> + Send + '_>> {
16 let url_ssh = format!("git@{}", self.get_remote_url());
17 Box::pin(async move {
18 let (stdout, stderr) = check_ssh_access(&url_ssh).await?;
19 if stdout.contains(self.get_username()) || stderr.contains(self.get_username()) {
20 Ok(())
21 } else {
22 let stdout_str = if stdout.is_empty() {
23 ""
24 } else {
25 &format!("stdout={} ", stdout.trim())
26 };
27 let stderr_str = if stderr.is_empty() {
28 ""
29 } else {
30 &format!("stderr={} ", stderr.trim())
31 };
32 Err(GitMoverError::new(format!(
33 "Cannot access to {url_ssh}: {stdout_str}{stderr_str}for {}",
34 self.get_type()
35 )))
36 }
37 })
38 }
39
40 fn create_repo(
42 &self,
43 repo: Repo,
44 ) -> Pin<Box<dyn std::future::Future<Output = Result<(), GitMoverError>> + Send + '_>>;
45
46 fn get_repo(
48 &self,
49 name: &str,
50 ) -> Pin<Box<dyn std::future::Future<Output = Result<Repo, GitMoverError>> + Send + '_>>;
51
52 fn edit_repo(
54 &self,
55 repo: Repo,
56 ) -> Pin<Box<dyn std::future::Future<Output = Result<(), GitMoverError>> + Send + '_>>;
57
58 fn get_all_repos(
60 &self,
61 ) -> Pin<Box<dyn std::future::Future<Output = Result<Vec<Repo>, GitMoverError>> + Send>>;
62
63 fn delete_repo(
65 &self,
66 name: &str,
67 ) -> Pin<Box<dyn std::future::Future<Output = Result<(), GitMoverError>> + Send + '_>>;
68
69 fn get_username(&self) -> &str;
71
72 fn get_remote_url(&self) -> String;
74
75 fn get_type(&self) -> PlatformType;
77}
78
79#[derive(Debug, Clone, PartialEq, Deserialize)]
81pub enum PlatformType {
82 Gitlab,
84
85 Github,
87
88 Codeberg,
90}
91
92impl std::fmt::Display for PlatformType {
93 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94 match self {
95 PlatformType::Gitlab => write!(f, "gitlab"),
96 PlatformType::Github => write!(f, "github"),
97 PlatformType::Codeberg => write!(f, "codeberg"),
98 }
99 }
100}
101
102impl From<String> for PlatformType {
103 fn from(s: String) -> Self {
104 match s.to_lowercase().as_str() {
105 "gitlab" => PlatformType::Gitlab,
106 "github" => PlatformType::Github,
107 "codeberg" => PlatformType::Codeberg,
108 _ => panic!("Invalid platform"),
109 }
110 }
111}