235 lines
7.0 KiB
Rust
235 lines
7.0 KiB
Rust
//! Rhai wrappers for Mycelium client module functions
|
|
//!
|
|
//! This module provides Rhai wrappers for the functions in the Mycelium client module.
|
|
|
|
use rhai::{Engine, EvalAltResult, Array, Dynamic, Map};
|
|
use crate::mycelium as client;
|
|
use tokio::runtime::Runtime;
|
|
use serde_json::Value;
|
|
use crate::rhai::error::ToRhaiError;
|
|
|
|
/// Register Mycelium module functions with the Rhai engine
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * `engine` - The Rhai engine to register the functions with
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// * `Result<(), Box<EvalAltResult>>` - Ok if registration was successful, Err otherwise
|
|
pub fn register_mycelium_module(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
|
|
// Register Mycelium client functions
|
|
engine.register_fn("mycelium_get_node_info", mycelium_get_node_info);
|
|
engine.register_fn("mycelium_list_peers", mycelium_list_peers);
|
|
engine.register_fn("mycelium_add_peer", mycelium_add_peer);
|
|
engine.register_fn("mycelium_remove_peer", mycelium_remove_peer);
|
|
engine.register_fn("mycelium_list_selected_routes", mycelium_list_selected_routes);
|
|
engine.register_fn("mycelium_list_fallback_routes", mycelium_list_fallback_routes);
|
|
engine.register_fn("mycelium_send_message", mycelium_send_message);
|
|
engine.register_fn("mycelium_receive_messages", mycelium_receive_messages);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
// Helper function to get a runtime
|
|
fn get_runtime() -> Result<Runtime, Box<EvalAltResult>> {
|
|
tokio::runtime::Runtime::new().map_err(|e| {
|
|
Box::new(EvalAltResult::ErrorRuntime(
|
|
format!("Failed to create Tokio runtime: {}", e).into(),
|
|
rhai::Position::NONE
|
|
))
|
|
})
|
|
}
|
|
|
|
// Helper function to convert serde_json::Value to rhai::Dynamic
|
|
fn value_to_dynamic(value: Value) -> Dynamic {
|
|
match value {
|
|
Value::Null => Dynamic::UNIT,
|
|
Value::Bool(b) => Dynamic::from(b),
|
|
Value::Number(n) => {
|
|
if let Some(i) = n.as_i64() {
|
|
Dynamic::from(i)
|
|
} else if let Some(f) = n.as_f64() {
|
|
Dynamic::from(f)
|
|
} else {
|
|
Dynamic::from(n.to_string())
|
|
}
|
|
},
|
|
Value::String(s) => Dynamic::from(s),
|
|
Value::Array(arr) => {
|
|
let mut rhai_arr = Array::new();
|
|
for item in arr {
|
|
rhai_arr.push(value_to_dynamic(item));
|
|
}
|
|
Dynamic::from(rhai_arr)
|
|
},
|
|
Value::Object(map) => {
|
|
let mut rhai_map = Map::new();
|
|
for (k, v) in map {
|
|
rhai_map.insert(k.into(), value_to_dynamic(v));
|
|
}
|
|
Dynamic::from_map(rhai_map)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Helper trait to convert String errors to Rhai errors
|
|
impl<T> ToRhaiError<T> for Result<T, String> {
|
|
fn to_rhai_error(self) -> Result<T, Box<EvalAltResult>> {
|
|
self.map_err(|e| {
|
|
Box::new(EvalAltResult::ErrorRuntime(
|
|
format!("Mycelium error: {}", e).into(),
|
|
rhai::Position::NONE
|
|
))
|
|
})
|
|
}
|
|
}
|
|
|
|
//
|
|
// Mycelium Client Function Wrappers
|
|
//
|
|
|
|
/// Wrapper for mycelium::get_node_info
|
|
///
|
|
/// Gets information about the Mycelium node.
|
|
pub fn mycelium_get_node_info(api_url: &str) -> Result<Dynamic, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
let result = rt.block_on(async {
|
|
client::get_node_info(api_url).await
|
|
});
|
|
|
|
let node_info = result.to_rhai_error()?;
|
|
|
|
Ok(value_to_dynamic(node_info))
|
|
}
|
|
|
|
/// Wrapper for mycelium::list_peers
|
|
///
|
|
/// Lists all peers connected to the Mycelium node.
|
|
pub fn mycelium_list_peers(api_url: &str) -> Result<Dynamic, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
let result = rt.block_on(async {
|
|
client::list_peers(api_url).await
|
|
});
|
|
|
|
let peers = result.to_rhai_error()?;
|
|
|
|
Ok(value_to_dynamic(peers))
|
|
}
|
|
|
|
/// Wrapper for mycelium::add_peer
|
|
///
|
|
/// Adds a new peer to the Mycelium node.
|
|
pub fn mycelium_add_peer(api_url: &str, peer_address: &str) -> Result<Dynamic, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
let result = rt.block_on(async {
|
|
client::add_peer(api_url, peer_address).await
|
|
});
|
|
|
|
let response = result.to_rhai_error()?;
|
|
|
|
Ok(value_to_dynamic(response))
|
|
}
|
|
|
|
/// Wrapper for mycelium::remove_peer
|
|
///
|
|
/// Removes a peer from the Mycelium node.
|
|
pub fn mycelium_remove_peer(api_url: &str, peer_id: &str) -> Result<Dynamic, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
let result = rt.block_on(async {
|
|
client::remove_peer(api_url, peer_id).await
|
|
});
|
|
|
|
let response = result.to_rhai_error()?;
|
|
|
|
Ok(value_to_dynamic(response))
|
|
}
|
|
|
|
/// Wrapper for mycelium::list_selected_routes
|
|
///
|
|
/// Lists all selected routes in the Mycelium node.
|
|
pub fn mycelium_list_selected_routes(api_url: &str) -> Result<Dynamic, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
let result = rt.block_on(async {
|
|
client::list_selected_routes(api_url).await
|
|
});
|
|
|
|
let routes = result.to_rhai_error()?;
|
|
|
|
Ok(value_to_dynamic(routes))
|
|
}
|
|
|
|
/// Wrapper for mycelium::list_fallback_routes
|
|
///
|
|
/// Lists all fallback routes in the Mycelium node.
|
|
pub fn mycelium_list_fallback_routes(api_url: &str) -> Result<Dynamic, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
let result = rt.block_on(async {
|
|
client::list_fallback_routes(api_url).await
|
|
});
|
|
|
|
let routes = result.to_rhai_error()?;
|
|
|
|
Ok(value_to_dynamic(routes))
|
|
}
|
|
|
|
/// Wrapper for mycelium::send_message
|
|
///
|
|
/// Sends a message to a destination via the Mycelium node.
|
|
pub fn mycelium_send_message(api_url: &str, destination: &str, topic: &str, message: &str, deadline_secs: i64) -> Result<Dynamic, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
// Convert deadline to u64
|
|
let deadline = if deadline_secs < 0 {
|
|
return Err(Box::new(EvalAltResult::ErrorRuntime(
|
|
"Deadline cannot be negative".into(),
|
|
rhai::Position::NONE
|
|
)));
|
|
} else {
|
|
deadline_secs as u64
|
|
};
|
|
|
|
let result = rt.block_on(async {
|
|
client::send_message(api_url, destination, topic, message, deadline).await
|
|
});
|
|
|
|
let response = result.to_rhai_error()?;
|
|
|
|
Ok(value_to_dynamic(response))
|
|
}
|
|
|
|
/// Wrapper for mycelium::receive_messages
|
|
///
|
|
/// Receives messages from a topic via the Mycelium node.
|
|
pub fn mycelium_receive_messages(api_url: &str, topic: &str, count: i64) -> Result<Dynamic, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
// Convert count to u32
|
|
let count = if count < 0 {
|
|
return Err(Box::new(EvalAltResult::ErrorRuntime(
|
|
"Count cannot be negative".into(),
|
|
rhai::Position::NONE
|
|
)));
|
|
} else if count > u32::MAX as i64 {
|
|
return Err(Box::new(EvalAltResult::ErrorRuntime(
|
|
format!("Count too large, maximum is {}", u32::MAX).into(),
|
|
rhai::Position::NONE
|
|
)));
|
|
} else {
|
|
count as u32
|
|
};
|
|
|
|
let result = rt.block_on(async {
|
|
client::receive_messages(api_url, topic, count).await
|
|
});
|
|
|
|
let messages = result.to_rhai_error()?;
|
|
|
|
Ok(value_to_dynamic(messages))
|
|
} |