aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart-vcs/src/driver/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/mozart-vcs/src/driver/mod.rs')
-rw-r--r--crates/mozart-vcs/src/driver/mod.rs131
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)),
}
}