diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-02-23 12:10:44 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-02-23 12:14:11 +0900 |
| commit | d8ecb21a7931ec6f1d7b447d0c15f53de32bfc45 (patch) | |
| tree | 0da1e0c2ec988905b98939b524b72217e83019de /crates/mozart-vcs/src/driver/mod.rs | |
| parent | 0080efea9386d46f65d1862fcb90eb44999d9761 (diff) | |
| download | php-mozart-d8ecb21a7931ec6f1d7b447d0c15f53de32bfc45.tar.gz php-mozart-d8ecb21a7931ec6f1d7b447d0c15f53de32bfc45.tar.zst php-mozart-d8ecb21a7931ec6f1d7b447d0c15f53de32bfc45.zip | |
refactor(vcs): convert VcsDriver trait to native async
Replace manual tokio::runtime::Handle::current().block_on() calls with
native async/await throughout all VCS drivers. Introduce AnyVcsDriver
enum for static dispatch to avoid dyn trait with async methods.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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)), } } |
