//! Rhai wrappers for Git module functions //! //! This module provides Rhai wrappers for the functions in the Git module. use crate::git::{GitError, GitRepo, GitTree}; use rhai::{Array, Dynamic, Engine, EvalAltResult}; /// Register Git module functions with the Rhai engine /// /// # Arguments /// /// * `engine` - The Rhai engine to register the functions with /// /// # Returns /// /// * `Result<(), Box>` - Ok if registration was successful, Err otherwise pub fn register_git_module(engine: &mut Engine) -> Result<(), Box> { // Register GitTree constructor engine.register_type::(); engine.register_fn("git_tree_new", git_tree_new); // Register GitTree methods engine.register_fn("list", git_tree_list); engine.register_fn("find", git_tree_find); engine.register_fn("get", git_tree_get); // Register GitRepo methods engine.register_type::(); engine.register_fn("path", git_repo_path); engine.register_fn("has_changes", git_repo_has_changes); engine.register_fn("pull", git_repo_pull); engine.register_fn("reset", git_repo_reset); engine.register_fn("commit", git_repo_commit); engine.register_fn("push", git_repo_push); // Register git_clone function for testing engine.register_fn("git_clone", git_clone); Ok(()) } // Helper functions for error conversion fn git_error_to_rhai_error(result: Result) -> Result> { result.map_err(|e| { Box::new(EvalAltResult::ErrorRuntime( format!("Git error: {}", e).into(), rhai::Position::NONE, )) }) } // // GitTree Function Wrappers // /// Wrapper for GitTree::new /// /// Creates a new GitTree with the specified base path. pub fn git_tree_new(base_path: &str) -> Result> { git_error_to_rhai_error(GitTree::new(base_path)) } /// Wrapper for GitTree::list /// /// Lists all git repositories under the base path. pub fn git_tree_list(git_tree: &mut GitTree) -> Result> { let repos = git_error_to_rhai_error(git_tree.list())?; // Convert Vec to Rhai Array let mut array = Array::new(); for repo in repos { array.push(Dynamic::from(repo)); } Ok(array) } /// Wrapper for GitTree::find /// /// Finds repositories matching a pattern and returns them as an array of GitRepo objects. /// Assumes the underlying GitTree::find Rust method now returns Result, GitError>. pub fn git_tree_find(git_tree: &mut GitTree, pattern: &str) -> Result> { let repos: Vec = git_error_to_rhai_error(git_tree.find(pattern))?; // Convert Vec to Rhai Array let mut array = Array::new(); for repo in repos { array.push(Dynamic::from(repo)); } Ok(array) } /// Wrapper for GitTree::get /// /// Gets a single GitRepo object based on an exact name or URL. /// The underlying Rust GitTree::get method returns Result, GitError>. /// This wrapper ensures that for Rhai, 'get' returns a single GitRepo or an error /// if zero or multiple repositories are found (for local names/patterns), /// or if a URL operation fails or unexpectedly yields not exactly one result. pub fn git_tree_get( git_tree: &mut GitTree, name_or_url: &str, ) -> Result> { let mut repos_vec: Vec = git_error_to_rhai_error(git_tree.get(name_or_url))?; match repos_vec.len() { 1 => Ok(repos_vec.remove(0)), // Efficient for Vec of size 1, transfers ownership 0 => Err(Box::new(EvalAltResult::ErrorRuntime( format!("Git error: Repository '{}' not found.", name_or_url).into(), rhai::Position::NONE, ))), _ => Err(Box::new(EvalAltResult::ErrorRuntime( format!( "Git error: Multiple repositories ({}) found matching '{}'. Use find() for patterns or provide a more specific name for get().", repos_vec.len(), name_or_url ) .into(), rhai::Position::NONE, ))), } } // // GitRepo Function Wrappers // /// Wrapper for GitRepo::path /// /// Gets the path of the repository. pub fn git_repo_path(git_repo: &mut GitRepo) -> String { git_repo.path().to_string() } /// Wrapper for GitRepo::has_changes /// /// Checks if the repository has uncommitted changes. pub fn git_repo_has_changes(git_repo: &mut GitRepo) -> Result> { git_error_to_rhai_error(git_repo.has_changes()) } /// Wrapper for GitRepo::pull /// /// Pulls the latest changes from the remote repository. pub fn git_repo_pull(git_repo: &mut GitRepo) -> Result> { git_error_to_rhai_error(git_repo.pull()) } /// Wrapper for GitRepo::reset /// /// Resets any local changes in the repository. pub fn git_repo_reset(git_repo: &mut GitRepo) -> Result> { git_error_to_rhai_error(git_repo.reset()) } /// Wrapper for GitRepo::commit /// /// Commits changes in the repository. pub fn git_repo_commit( git_repo: &mut GitRepo, message: &str, ) -> Result> { git_error_to_rhai_error(git_repo.commit(message)) } /// Wrapper for GitRepo::push /// /// Pushes changes to the remote repository. pub fn git_repo_push(git_repo: &mut GitRepo) -> Result> { git_error_to_rhai_error(git_repo.push()) } /// Dummy implementation of git_clone for testing /// /// This function is used for testing the git module. pub fn git_clone(url: &str) -> Result<(), Box> { // This is a dummy implementation that always fails with a Git error Err(Box::new(EvalAltResult::ErrorRuntime( format!("Git error: Failed to clone repository from URL: {}", url).into(), rhai::Position::NONE, ))) }