diff options
Diffstat (limited to 'crates/mozart-vcs/src/driver/mod.rs')
| -rw-r--r-- | crates/mozart-vcs/src/driver/mod.rs | 131 |
1 files changed, 110 insertions, 21 deletions
diff --git a/crates/mozart-vcs/src/driver/mod.rs b/crates/mozart-vcs/src/driver/mod.rs index f8e26ef..7a132ed 100644 --- a/crates/mozart-vcs/src/driver/mod.rs +++ b/crates/mozart-vcs/src/driver/mod.rs @@ -79,30 +79,31 @@ pub enum DriverType { /// The VCS driver interface. /// /// Corresponds to Composer's `VcsDriverInterface`. -pub trait VcsDriver { +trait VcsDriver { /// Initialize the driver (e.g., clone mirror, fetch API metadata). - fn initialize(&mut self) -> Result<()>; + async fn initialize(&mut self) -> Result<()>; /// The root identifier (default branch/trunk). fn root_identifier(&self) -> &str; /// All branches as `name -> commit_hash`. - fn branches(&mut self) -> Result<&BTreeMap<String, String>>; + async fn branches(&mut self) -> Result<&BTreeMap<String, String>>; /// All tags as `name -> commit_hash`. - fn tags(&mut self) -> Result<&BTreeMap<String, String>>; + async fn tags(&mut self) -> Result<&BTreeMap<String, String>>; /// Get composer.json content parsed as JSON for a given identifier. - fn composer_information(&mut self, identifier: &str) -> Result<Option<serde_json::Value>>; + async fn composer_information(&mut self, identifier: &str) + -> Result<Option<serde_json::Value>>; /// Get raw file content at a given path and identifier. - fn file_content(&self, file: &str, identifier: &str) -> Result<Option<String>>; + async fn file_content(&self, file: &str, identifier: &str) -> Result<Option<String>>; /// Get the change date for a given identifier (ISO 8601). - fn change_date(&self, identifier: &str) -> Result<Option<String>>; + async fn change_date(&self, identifier: &str) -> Result<Option<String>>; /// Get the dist reference for a given identifier. - fn dist(&self, identifier: &str) -> Result<Option<DistReference>>; + async fn dist(&self, identifier: &str) -> Result<Option<DistReference>>; /// Get the source reference for a given identifier. fn source(&self, identifier: &str) -> SourceReference; @@ -111,7 +112,97 @@ pub trait VcsDriver { fn url(&self) -> &str; /// Clean up resources (temp dirs, etc.). - fn cleanup(&mut self) -> Result<()>; + async fn cleanup(&mut self) -> Result<()>; +} + +/// Enum-dispatched VCS driver. +/// +/// Wraps all concrete driver types to allow static dispatch with async trait methods. +pub enum AnyVcsDriver { + GitHub(github::GitHubDriver), + GitLab(gitlab::GitLabDriver), + Bitbucket(bitbucket::BitbucketDriver), + Forgejo(forgejo::ForgejoDriver), + Git(git::GitDriver), + Svn(svn::SvnDriver), + Hg(hg::HgDriver), +} + +macro_rules! dispatch { + ($self:expr, $method:ident $(, $arg:expr)*) => { + match $self { + AnyVcsDriver::GitHub(d) => d.$method($($arg),*), + AnyVcsDriver::GitLab(d) => d.$method($($arg),*), + AnyVcsDriver::Bitbucket(d) => d.$method($($arg),*), + AnyVcsDriver::Forgejo(d) => d.$method($($arg),*), + AnyVcsDriver::Git(d) => d.$method($($arg),*), + AnyVcsDriver::Svn(d) => d.$method($($arg),*), + AnyVcsDriver::Hg(d) => d.$method($($arg),*), + } + }; +} + +macro_rules! dispatch_async { + ($self:expr, $method:ident $(, $arg:expr)*) => { + match $self { + AnyVcsDriver::GitHub(d) => d.$method($($arg),*).await, + AnyVcsDriver::GitLab(d) => d.$method($($arg),*).await, + AnyVcsDriver::Bitbucket(d) => d.$method($($arg),*).await, + AnyVcsDriver::Forgejo(d) => d.$method($($arg),*).await, + AnyVcsDriver::Git(d) => d.$method($($arg),*).await, + AnyVcsDriver::Svn(d) => d.$method($($arg),*).await, + AnyVcsDriver::Hg(d) => d.$method($($arg),*).await, + } + }; +} + +impl AnyVcsDriver { + pub async fn initialize(&mut self) -> Result<()> { + dispatch_async!(self, initialize) + } + + pub fn root_identifier(&self) -> &str { + dispatch!(self, root_identifier) + } + + pub async fn branches(&mut self) -> Result<&BTreeMap<String, String>> { + dispatch_async!(self, branches) + } + + pub async fn tags(&mut self) -> Result<&BTreeMap<String, String>> { + dispatch_async!(self, tags) + } + + pub async fn composer_information( + &mut self, + identifier: &str, + ) -> Result<Option<serde_json::Value>> { + dispatch_async!(self, composer_information, identifier) + } + + pub async fn file_content(&self, file: &str, identifier: &str) -> Result<Option<String>> { + dispatch_async!(self, file_content, file, identifier) + } + + pub async fn change_date(&self, identifier: &str) -> Result<Option<String>> { + dispatch_async!(self, change_date, identifier) + } + + pub async fn dist(&self, identifier: &str) -> Result<Option<DistReference>> { + dispatch_async!(self, dist, identifier) + } + + pub fn source(&self, identifier: &str) -> SourceReference { + dispatch!(self, source, identifier) + } + + pub fn url(&self) -> &str { + dispatch!(self, url) + } + + pub async fn cleanup(&mut self) -> Result<()> { + dispatch_async!(self, cleanup) + } } /// Detect which driver type should handle a given URL. @@ -182,18 +273,16 @@ pub fn detect_driver( } /// Create a driver instance for the given URL and type. -pub fn create_driver( - url: &str, - driver_type: DriverType, - config: DriverConfig, -) -> Box<dyn VcsDriver> { +pub fn create_driver(url: &str, driver_type: DriverType, config: DriverConfig) -> AnyVcsDriver { match driver_type { - DriverType::GitHub => Box::new(github::GitHubDriver::new(url, config)), - DriverType::GitLab => Box::new(gitlab::GitLabDriver::new(url, config)), - DriverType::Bitbucket => Box::new(bitbucket::BitbucketDriver::new(url, config)), - DriverType::Forgejo => Box::new(forgejo::ForgejoDriver::new(url, config)), - DriverType::Git => Box::new(git::GitDriver::new(url, config)), - DriverType::Svn => Box::new(svn::SvnDriver::new(url, config)), - DriverType::Hg => Box::new(hg::HgDriver::new(url, config)), + DriverType::GitHub => AnyVcsDriver::GitHub(github::GitHubDriver::new(url, config)), + DriverType::GitLab => AnyVcsDriver::GitLab(gitlab::GitLabDriver::new(url, config)), + DriverType::Bitbucket => { + AnyVcsDriver::Bitbucket(bitbucket::BitbucketDriver::new(url, config)) + } + DriverType::Forgejo => AnyVcsDriver::Forgejo(forgejo::ForgejoDriver::new(url, config)), + DriverType::Git => AnyVcsDriver::Git(git::GitDriver::new(url, config)), + DriverType::Svn => AnyVcsDriver::Svn(svn::SvnDriver::new(url, config)), + DriverType::Hg => AnyVcsDriver::Hg(hg::HgDriver::new(url, config)), } } |
