Compare commits
No commits in common. "development_timur" and "main" have entirely different histories.
developmen
...
main
@ -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(())
|
|
||||||
}
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
pub mod engine;
|
|
||||||
pub mod wrapper;
|
|
||||||
pub mod generic_wrapper;
|
|
||||||
pub mod module;
|
|
@ -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
|
|
||||||
}
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user