Compare commits

..

No commits in common. "development_timur" and "main" have entirely different histories.

5 changed files with 0 additions and 463 deletions

View File

@ -1,49 +0,0 @@
//! Rhai engine creation and registration for Git module
//!
//! This module provides functions to create and configure a Rhai engine with Git functionality.
use rhai::{Engine, EvalAltResult};
use crate::git::{GitTree, GitRepo};
use super::wrapper::{
create_git_tree, list_repositories, find_repositories, get_repositories,
get_repo_path, has_changes, pull_repository, reset_repository,
commit_changes, push_changes, parse_git_url_wrapper
};
/// Create a Rhai engine with Git functionality
pub fn create_rhai_engine() -> Engine {
let mut engine = Engine::new();
// Register the Git module
register_git_module(&mut engine).expect("Failed to register Git module");
engine
}
/// Register Git module functions with the Rhai engine
pub fn register_git_module(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
// Register GitTree constructor
engine.register_fn("new_git_tree", create_git_tree);
// Register GitTree methods
engine.register_fn("list_repositories", list_repositories);
engine.register_fn("find_repositories", find_repositories);
engine.register_fn("get_repositories", get_repositories);
// Register GitRepo methods
engine.register_fn("get_repo_path", get_repo_path);
engine.register_fn("has_changes", has_changes);
engine.register_fn("pull_repository", pull_repository);
engine.register_fn("reset_repository", reset_repository);
engine.register_fn("commit_changes", commit_changes);
engine.register_fn("push_changes", push_changes);
// Register utility functions
engine.register_fn("parse_git_url", parse_git_url_wrapper);
// Register types
engine.register_type_with_name::<GitTree>("GitTree");
engine.register_type_with_name::<GitRepo>("GitRepo");
Ok(())
}

View File

@ -1,132 +0,0 @@
use std::collections::HashMap;
use rhai::{Dynamic, Map, Array};
/// Local wrapper trait for sal::rhai::ToRhai to avoid orphan rule violations
pub trait ToRhai {
/// Convert to a Rhai Dynamic value
fn to_rhai(&self) -> Dynamic;
}
// Implementation of ToRhai for Dynamic
impl ToRhai for Dynamic {
fn to_rhai(&self) -> Dynamic {
self.clone()
}
}
/// Generic trait for wrapping Rust functions to be used with Rhai
pub trait RhaiWrapper {
/// Wrap a function that takes ownership of self
fn wrap_consuming<F, R>(self, f: F) -> Dynamic
where
Self: Sized + Clone,
F: FnOnce(Self) -> R,
R: ToRhai;
/// Wrap a function that takes a mutable reference to self
fn wrap_mut<F, R>(&mut self, f: F) -> Dynamic
where
Self: Sized + Clone,
F: FnOnce(&mut Self) -> R,
R: ToRhai;
/// Wrap a function that takes an immutable reference to self
fn wrap<F, R>(&self, f: F) -> Dynamic
where
Self: Sized + Clone,
F: FnOnce(&Self) -> R,
R: ToRhai;
}
/// Implementation of RhaiWrapper for any type
impl<T> RhaiWrapper for T {
fn wrap_consuming<F, R>(self, f: F) -> Dynamic
where
Self: Sized + Clone,
F: FnOnce(Self) -> R,
R: ToRhai,
{
let result = f(self);
result.to_rhai()
}
fn wrap_mut<F, R>(&mut self, f: F) -> Dynamic
where
Self: Sized + Clone,
F: FnOnce(&mut Self) -> R,
R: ToRhai,
{
let result = f(self);
result.to_rhai()
}
fn wrap<F, R>(&self, f: F) -> Dynamic
where
Self: Sized + Clone,
F: FnOnce(&Self) -> R,
R: ToRhai,
{
let result = f(self);
result.to_rhai()
}
}
/// Convert a Rhai Map to a Rust HashMap
pub fn map_to_hashmap(map: &Map) -> HashMap<String, String> {
let mut result = HashMap::new();
for (key, value) in map.iter() {
let k = key.clone().to_string();
let v = value.clone().to_string();
if !k.is_empty() && !v.is_empty() {
result.insert(k, v);
}
}
result
}
/// Convert a HashMap<String, String> to a Rhai Map
pub fn hashmap_to_map(map: &HashMap<String, String>) -> Map {
let mut result = Map::new();
for (key, value) in map.iter() {
result.insert(key.clone().into(), Dynamic::from(value.clone()));
}
result
}
/// Convert a Rhai Array to a Vec of strings
pub fn array_to_vec_string(array: &Array) -> Vec<String> {
array.iter()
.filter_map(|item| {
let s = item.clone().to_string();
if !s.is_empty() { Some(s) } else { None }
})
.collect()
}
/// Helper function to convert Dynamic to Option<String>
pub fn dynamic_to_string_option(value: &Dynamic) -> Option<String> {
if value.is_string() {
Some(value.clone().to_string())
} else {
None
}
}
/// Helper function to convert Dynamic to Option<u32>
pub fn dynamic_to_u32_option(value: &Dynamic) -> Option<u32> {
if value.is_int() {
Some(value.as_int().unwrap() as u32)
} else {
None
}
}
/// Helper function to convert Dynamic to Option<&str> with lifetime management
pub fn dynamic_to_str_option<'a>(value: &Dynamic, storage: &'a mut String) -> Option<&'a str> {
if value.is_string() {
*storage = value.clone().to_string();
Some(storage.as_str())
} else {
None
}
}

View File

@ -1,4 +0,0 @@
pub mod engine;
pub mod wrapper;
pub mod generic_wrapper;
pub mod module;

View File

@ -1,106 +0,0 @@
use rhai::{Dynamic, Engine, EvalAltResult, Module, NativeCallContext, FuncRegistration, FnNamespace, Identifier};
use std::sync::Arc;
use crate::git::{GitTree, GitRepo};
use super::wrapper;
/// Creates and returns a Rhai module with Git functionality.
///
/// This module exposes Git-related functions to Rhai scripts.
pub fn create_git_module() -> Module {
let mut module = Module::new();
// Register GitTree functions
FuncRegistration::new("create_git_tree")
.with_namespace(FnNamespace::Global)
.with_params_info(["base_path: &str", "GitTree"])
.with_comments(["/// Create a new GitTree with the specified base path",
"/// - base_path: Base directory path to search for git repositories",
"/// Returns a GitTree instance"])
.set_into_module(&mut module, wrapper::create_git_tree);
FuncRegistration::new("list_repositories")
.with_namespace(FnNamespace::Global)
.with_params_info(["tree: &mut GitTree", "Array"])
.with_comments(["/// List all git repositories under the base path",
"/// - tree: GitTree instance",
"/// Returns an array of GitRepo instances"])
.set_into_module(&mut module, wrapper::list_repositories);
FuncRegistration::new("find_repositories")
.with_namespace(FnNamespace::Global)
.with_params_info(["tree: &mut GitTree", "pattern: &str", "Array"])
.with_comments(["/// Find repositories matching a pattern",
"/// - tree: GitTree instance",
"/// - pattern: Pattern to match repository names",
"/// Returns an array of matching GitRepo instances"])
.set_into_module(&mut module, wrapper::find_repositories);
FuncRegistration::new("get_repositories")
.with_namespace(FnNamespace::Global)
.with_params_info(["tree: &mut GitTree", "path_or_url: &str", "Array"])
.with_comments(["/// Get repositories based on a path pattern or URL",
"/// - tree: GitTree instance",
"/// - path_or_url: Path pattern or URL to match",
"/// Returns an array of matching GitRepo instances"])
.set_into_module(&mut module, wrapper::get_repositories);
// Register GitRepo functions
FuncRegistration::new("get_repo_path")
.with_namespace(FnNamespace::Global)
.with_params_info(["repo: &mut GitRepo", "String"])
.with_comments(["/// Get the path of the repository",
"/// - repo: GitRepo instance",
"/// Returns the path of the repository as a string"])
.set_into_module(&mut module, wrapper::get_repo_path);
FuncRegistration::new("has_changes")
.with_namespace(FnNamespace::Global)
.with_params_info(["repo: &mut GitRepo", "bool"])
.with_comments(["/// Check if the repository has uncommitted changes",
"/// - repo: GitRepo instance",
"/// Returns true if there are uncommitted changes, false otherwise"])
.set_into_module(&mut module, wrapper::has_changes);
FuncRegistration::new("pull_repository")
.with_namespace(FnNamespace::Global)
.with_params_info(["repo: &mut GitRepo", "String"])
.with_comments(["/// Pull the latest changes from the remote repository",
"/// - repo: GitRepo instance",
"/// Returns a success message or throws an error"])
.set_into_module(&mut module, wrapper::pull_repository);
FuncRegistration::new("reset_repository")
.with_namespace(FnNamespace::Global)
.with_params_info(["repo: &mut GitRepo", "String"])
.with_comments(["/// Reset any local changes in the repository",
"/// - repo: GitRepo instance",
"/// Returns a success message or throws an error"])
.set_into_module(&mut module, wrapper::reset_repository);
FuncRegistration::new("commit_changes")
.with_namespace(FnNamespace::Global)
.with_params_info(["repo: &mut GitRepo", "message: &str", "String"])
.with_comments(["/// Commit changes in the repository",
"/// - repo: GitRepo instance",
"/// - message: Commit message",
"/// Returns a success message or throws an error"])
.set_into_module(&mut module, wrapper::commit_changes);
FuncRegistration::new("push_changes")
.with_namespace(FnNamespace::Global)
.with_params_info(["repo: &mut GitRepo", "String"])
.with_comments(["/// Push changes to the remote repository",
"/// - repo: GitRepo instance",
"/// Returns a success message or throws an error"])
.set_into_module(&mut module, wrapper::push_changes);
FuncRegistration::new("parse_git_url")
.with_namespace(FnNamespace::Global)
.with_params_info(["url: &str", "Array"])
.with_comments(["/// Parse a git URL to extract the server, account, and repository name",
"/// - url: Git URL to parse",
"/// Returns an array with [server, account, repo]"])
.set_into_module(&mut module, wrapper::parse_git_url_wrapper);
module
}

View File

@ -1,172 +0,0 @@
//! Rhai wrappers for Git module functions
//!
//! This module provides Rhai wrappers for the functions in the Git module.
use rhai::{EvalAltResult, Array, Dynamic, Position};
use crate::git::{GitTree, GitRepo, GitError, parse_git_url};
use super::generic_wrapper::{RhaiWrapper, ToRhai};
// Helper function to convert GitError to EvalAltResult
fn git_error_to_rhai_error<T>(result: Result<T, GitError>) -> Result<T, Box<EvalAltResult>> {
result.map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(
format!("Git error: {}", e).into(),
Position::NONE
))
})
}
//
// GitTree Functions
//
/// Create a new GitTree with the specified base path
pub fn create_git_tree(base_path: &str) -> Result<GitTree, Box<EvalAltResult>> {
git_error_to_rhai_error(GitTree::new(base_path))
}
/// List all git repositories under the base path
pub fn list_repositories(tree: &mut GitTree) -> Result<Array, Box<EvalAltResult>> {
git_error_to_rhai_error(tree.list()).map(|repos| {
let array: Array = repos.into_iter()
.map(|repo| Dynamic::from(repo))
.collect();
array
})
}
/// Find repositories matching a pattern
pub fn find_repositories(tree: &mut GitTree, pattern: &str) -> Result<Array, Box<EvalAltResult>> {
git_error_to_rhai_error(tree.find(pattern)).map(|repos| {
let array: Array = repos.into_iter()
.map(|repo| Dynamic::from(repo))
.collect();
array
})
}
/// Get repositories based on a path pattern or URL
pub fn get_repositories(tree: &mut GitTree, path_or_url: &str) -> Result<Array, Box<EvalAltResult>> {
git_error_to_rhai_error(tree.get(path_or_url)).map(|repos| {
let array: Array = repos.into_iter()
.map(Dynamic::from)
.collect();
array
})
}
//
// GitRepo Functions
//
/// Get the path of the repository
pub fn get_repo_path(repo: &mut GitRepo) -> String {
repo.path().to_string()
}
/// Check if the repository has uncommitted changes
pub fn has_changes(repo: &mut GitRepo) -> Result<bool, Box<EvalAltResult>> {
git_error_to_rhai_error(repo.has_changes())
}
/// Pull the latest changes from the remote repository
pub fn pull_repository(repo: &mut GitRepo) -> Result<String, Box<EvalAltResult>> {
match repo.pull() {
Ok(_) => Ok(String::from("Successfully pulled changes")),
Err(err) => Err(Box::new(EvalAltResult::ErrorRuntime(
format!("Error pulling changes: {}", err).into(),
Position::NONE
)))
}
}
/// Reset any local changes in the repository
pub fn reset_repository(repo: &mut GitRepo) -> Result<String, Box<EvalAltResult>> {
match repo.reset() {
Ok(_) => Ok(String::from("Successfully reset repository")),
Err(err) => Err(Box::new(EvalAltResult::ErrorRuntime(
format!("Error resetting repository: {}", err).into(),
Position::NONE
)))
}
}
/// Commit changes in the repository
pub fn commit_changes(repo: &mut GitRepo, message: &str) -> Result<String, Box<EvalAltResult>> {
match repo.commit(message) {
Ok(_) => Ok(String::from("Successfully committed changes")),
Err(err) => Err(Box::new(EvalAltResult::ErrorRuntime(
format!("Error committing changes: {}", err).into(),
Position::NONE
)))
}
}
/// Push changes to the remote repository
pub fn push_changes(repo: &mut GitRepo) -> Result<String, Box<EvalAltResult>> {
match repo.push() {
Ok(_) => Ok(String::from("Successfully pushed changes")),
Err(err) => Err(Box::new(EvalAltResult::ErrorRuntime(
format!("Error pushing changes: {}", err).into(),
Position::NONE
)))
}
}
/// Parse a git URL to extract the server, account, and repository name
pub fn parse_git_url_wrapper(url: &str) -> Array {
let (server, account, repo) = parse_git_url(url);
let mut array = Array::new();
array.push(Dynamic::from(server));
array.push(Dynamic::from(account));
array.push(Dynamic::from(repo));
array
}
// Implementation of ToRhai for GitTree
impl ToRhai for GitTree {
fn to_rhai(&self) -> Dynamic {
Dynamic::from(self.clone())
}
}
// Implementation of ToRhai for GitRepo
impl ToRhai for GitRepo {
fn to_rhai(&self) -> Dynamic {
Dynamic::from(self.clone())
}
}
// Implementation of ToRhai for String
impl ToRhai for String {
fn to_rhai(&self) -> Dynamic {
Dynamic::from(self.clone())
}
}
// Implementation of ToRhai for bool
impl ToRhai for bool {
fn to_rhai(&self) -> Dynamic {
Dynamic::from(*self)
}
}
// Implementation of ToRhai for Vec<String>
impl ToRhai for Vec<String> {
fn to_rhai(&self) -> Dynamic {
let array: Array = self.iter()
.map(|s| Dynamic::from(s.clone()))
.collect();
Dynamic::from(array)
}
}
// Implementation of ToRhai for Option<GitRepo>
impl<T: ToRhai> ToRhai for Option<T> {
fn to_rhai(&self) -> Dynamic {
match self {
Some(value) => value.to_rhai(),
None => Dynamic::UNIT
}
}
}