more efforts to automate rhai bindings
This commit is contained in:
176
rhai_wrapper/examples/rust_rhai_wrapper_example.rs
Normal file
176
rhai_wrapper/examples/rust_rhai_wrapper_example.rs
Normal file
@@ -0,0 +1,176 @@
|
||||
use rhai::Engine;
|
||||
use rhai_wrapper::rust_rhai_wrapper;
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
|
||||
// Define a custom error type for Result examples
|
||||
#[derive(Debug, Clone)]
|
||||
struct MyError(String);
|
||||
|
||||
impl fmt::Display for MyError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for MyError {}
|
||||
|
||||
impl From<String> for MyError {
|
||||
fn from(s: String) -> Self {
|
||||
MyError(s)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Create a Rhai engine
|
||||
let mut engine = Engine::new();
|
||||
|
||||
// 1. Basic example: Add two numbers
|
||||
// Define the original Rust function
|
||||
fn add(a: i32, b: i32) -> i32 {
|
||||
a + b
|
||||
}
|
||||
|
||||
// Register it with Rhai
|
||||
engine.register_fn("add_rhai", add);
|
||||
|
||||
// Create a wrapper function that calls Rhai which calls the Rust function
|
||||
rust_rhai_wrapper!(add_via_rhai, "add_rhai", (i32, i32) -> i32);
|
||||
|
||||
// Test the full circle
|
||||
let result = add_via_rhai(&mut engine, 5, 3);
|
||||
println!("add_via_rhai(5, 3) = {}", result);
|
||||
|
||||
// 2. String manipulation example
|
||||
fn concat(s1: String, s2: String) -> String {
|
||||
format!("{} {}", s1, s2)
|
||||
}
|
||||
|
||||
engine.register_fn("concat_rhai", concat);
|
||||
rust_rhai_wrapper!(concat_via_rhai, "concat_rhai", (String, String) -> String);
|
||||
|
||||
let result = concat_via_rhai(&mut engine, "Hello".to_string(), "World".to_string());
|
||||
println!("concat_via_rhai(\"Hello\", \"World\") = {}", result);
|
||||
|
||||
// 3. Function with no arguments
|
||||
fn get_random() -> i32 {
|
||||
42 // Not so random, but it's just an example
|
||||
}
|
||||
|
||||
engine.register_fn("get_random_rhai", get_random);
|
||||
rust_rhai_wrapper!(get_random_via_rhai, "get_random_rhai", () -> i32);
|
||||
|
||||
let result = get_random_via_rhai(&mut engine);
|
||||
println!("get_random_via_rhai() = {}", result);
|
||||
|
||||
// 4. Function with more arguments
|
||||
fn calculate(a: i32, b: i32, c: i32, d: i32) -> i32 {
|
||||
a + b * c - d
|
||||
}
|
||||
|
||||
engine.register_fn("calculate_rhai", calculate);
|
||||
rust_rhai_wrapper!(calculate_via_rhai, "calculate_rhai", (i32, i32, i32, i32) -> i32);
|
||||
|
||||
let result = calculate_via_rhai(&mut engine, 5, 3, 2, 1);
|
||||
println!("calculate_via_rhai(5, 3, 2, 1) = {}", result);
|
||||
|
||||
// 5. Function that handles errors with a custom return type
|
||||
fn divide(a: i32, b: i32) -> Result<i32, String> {
|
||||
if b == 0 {
|
||||
Err("Division by zero".to_string())
|
||||
} else {
|
||||
Ok(a / b)
|
||||
}
|
||||
}
|
||||
|
||||
// Register a safe division function that returns an array with success flag and result/error
|
||||
engine.register_fn("safe_divide", |a: i32, b: i32| -> rhai::Array {
|
||||
if b == 0 {
|
||||
// Return [false, error message]
|
||||
let mut arr = rhai::Array::new();
|
||||
arr.push(rhai::Dynamic::from(false));
|
||||
arr.push(rhai::Dynamic::from("Division by zero"));
|
||||
arr
|
||||
} else {
|
||||
// Return [true, result]
|
||||
let mut arr = rhai::Array::new();
|
||||
arr.push(rhai::Dynamic::from(true));
|
||||
arr.push(rhai::Dynamic::from(a / b));
|
||||
arr
|
||||
}
|
||||
});
|
||||
|
||||
// Create a wrapper for the safe_divide function
|
||||
rust_rhai_wrapper!(safe_divide_via_rhai, "safe_divide", (i32, i32) -> rhai::Array);
|
||||
|
||||
// Test success case
|
||||
let result = safe_divide_via_rhai(&mut engine, 10, 2);
|
||||
println!("safe_divide_via_rhai(10, 2) = {:?}", result);
|
||||
|
||||
// Test error case
|
||||
let result = safe_divide_via_rhai(&mut engine, 10, 0);
|
||||
println!("safe_divide_via_rhai(10, 0) = {:?}", result);
|
||||
|
||||
// Process the result
|
||||
let success = result[0].as_bool().unwrap();
|
||||
if success {
|
||||
println!("Division result: {}", result[1].as_int().unwrap());
|
||||
} else {
|
||||
println!("Division error: {}", result[1].clone().into_string().unwrap());
|
||||
}
|
||||
|
||||
// 6. Complex example: Using a custom type with Rhai
|
||||
#[derive(Debug, Clone)]
|
||||
struct Person {
|
||||
name: String,
|
||||
age: i32,
|
||||
}
|
||||
|
||||
// Register type and methods with Rhai
|
||||
engine.register_type::<Person>();
|
||||
engine.register_fn("new_person", |name: String, age: i32| -> Person {
|
||||
Person { name, age }
|
||||
});
|
||||
engine.register_fn("get_name", |p: &mut Person| -> String {
|
||||
p.name.clone()
|
||||
});
|
||||
engine.register_fn("get_age", |p: &mut Person| -> i32 {
|
||||
p.age
|
||||
});
|
||||
engine.register_fn("is_adult", |p: &mut Person| -> bool {
|
||||
p.age >= 18
|
||||
});
|
||||
|
||||
// Register a function that creates a person and checks if they're an adult
|
||||
engine.register_fn("create_and_check_person", |name: String, age: i32| -> rhai::Array {
|
||||
let person = Person { name, age };
|
||||
let is_adult = person.age >= 18;
|
||||
|
||||
// Create an array with the person and the is_adult flag
|
||||
let mut arr = rhai::Array::new();
|
||||
|
||||
// Convert the person to a map for Rhai
|
||||
let mut map = rhai::Map::new();
|
||||
map.insert("name".into(), rhai::Dynamic::from(person.name));
|
||||
map.insert("age".into(), rhai::Dynamic::from(person.age));
|
||||
|
||||
arr.push(rhai::Dynamic::from(map));
|
||||
arr.push(rhai::Dynamic::from(is_adult));
|
||||
arr
|
||||
});
|
||||
|
||||
// Create a wrapper for the Rhai function
|
||||
rust_rhai_wrapper!(create_person_via_rhai, "create_and_check_person", (String, i32) -> rhai::Array);
|
||||
|
||||
// Test the wrapper
|
||||
let result = create_person_via_rhai(&mut engine, "Alice".to_string(), 25);
|
||||
println!("create_person_via_rhai(\"Alice\", 25) = {:?}", result);
|
||||
|
||||
// Extract data from the Rhai array
|
||||
let person_map = result[0].clone().try_cast::<rhai::Map>().expect("Expected a Map");
|
||||
let is_adult = result[1].clone().as_bool().expect("Expected a boolean");
|
||||
|
||||
println!("Person: {:?}, Is Adult: {}", person_map, is_adult);
|
||||
|
||||
println!("All examples completed successfully!");
|
||||
}
|
312
rhai_wrapper/examples/user_management_example.rs
Normal file
312
rhai_wrapper/examples/user_management_example.rs
Normal file
@@ -0,0 +1,312 @@
|
||||
use rhai::{Engine, INT, CustomType, TypeBuilder};
|
||||
use rhai_wrapper::{wrap_option_return, wrap_vec_return};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::path::Path;
|
||||
use chrono;
|
||||
|
||||
// --- Mock heromodels_core ---
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, CustomType)]
|
||||
pub struct BaseModelData {
|
||||
pub id: u32,
|
||||
pub created_at: i64, // Using i64 for timestamp simplicity
|
||||
pub updated_at: i64,
|
||||
pub comment_ids: Vec<u32>,
|
||||
}
|
||||
|
||||
impl BaseModelData {
|
||||
pub fn new(id: u32) -> Self {
|
||||
let now = chrono::Utc::now().timestamp();
|
||||
Self {
|
||||
id,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
comment_ids: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
// No &mut self for getters if struct is Clone and passed by value in Rhai, or if Rhai handles it.
|
||||
// For CustomType, Rhai typically passes &mut T to getters/setters.
|
||||
pub fn get_id(&mut self) -> u32 { self.id }
|
||||
pub fn get_created_at(&mut self) -> i64 { self.created_at }
|
||||
pub fn get_updated_at(&mut self) -> i64 { self.updated_at }
|
||||
pub fn get_comment_ids(&mut self) -> Vec<u32> { self.comment_ids.clone() }
|
||||
|
||||
pub fn add_comment_internal(&mut self, comment_id: u32) { // Renamed to avoid clash if also exposed
|
||||
self.comment_ids.push(comment_id);
|
||||
self.updated_at = chrono::Utc::now().timestamp();
|
||||
}
|
||||
}
|
||||
|
||||
// --- User Struct and Methods (Adapted for Rhai) ---
|
||||
|
||||
/// Represents a user in the system
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, CustomType)]
|
||||
pub struct User {
|
||||
/// Base model data
|
||||
pub base_data: BaseModelData,
|
||||
|
||||
/// User's username
|
||||
pub username: String,
|
||||
|
||||
/// User's email address
|
||||
pub email: String,
|
||||
|
||||
/// User's full name
|
||||
pub full_name: String,
|
||||
|
||||
/// Whether the user is active
|
||||
pub is_active: bool,
|
||||
}
|
||||
|
||||
impl User {
|
||||
// This is the "builder" entry point
|
||||
pub fn user_builder(id: INT) -> Self {
|
||||
Self {
|
||||
base_data: BaseModelData::new(id as u32),
|
||||
username: String::new(),
|
||||
email: String::new(),
|
||||
full_name: String::new(),
|
||||
is_active: true, // Default, can be changed by .is_active(false)
|
||||
}
|
||||
}
|
||||
|
||||
// Fluent setters returning Self
|
||||
pub fn username(mut self, username: String) -> Self {
|
||||
self.username = username;
|
||||
self.base_data.updated_at = chrono::Utc::now().timestamp();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn email(mut self, email: String) -> Self {
|
||||
self.email = email;
|
||||
self.base_data.updated_at = chrono::Utc::now().timestamp();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn full_name(mut self, full_name: String) -> Self {
|
||||
self.full_name = full_name;
|
||||
self.base_data.updated_at = chrono::Utc::now().timestamp();
|
||||
self
|
||||
}
|
||||
|
||||
// Naming this 'set_is_active' to distinguish from potential getter 'is_active'
|
||||
// or the script can use direct field access if setter is also registered for 'is_active'
|
||||
// For fluent chain .is_active(bool_val)
|
||||
pub fn is_active(mut self, active_status: bool) -> Self {
|
||||
self.is_active = active_status;
|
||||
self.base_data.updated_at = chrono::Utc::now().timestamp();
|
||||
self
|
||||
}
|
||||
|
||||
// Method to add a comment, distinct from direct field manipulation
|
||||
pub fn add_comment(mut self, comment_id: INT) -> Self {
|
||||
self.base_data.add_comment_internal(comment_id as u32);
|
||||
self
|
||||
}
|
||||
|
||||
// Explicit activate/deactivate methods returning Self for chaining if needed
|
||||
pub fn activate(mut self) -> Self {
|
||||
self.is_active = true;
|
||||
self.base_data.updated_at = chrono::Utc::now().timestamp();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn deactivate(mut self) -> Self {
|
||||
self.is_active = false;
|
||||
self.base_data.updated_at = chrono::Utc::now().timestamp();
|
||||
self
|
||||
}
|
||||
|
||||
// Getters for direct field access from Rhai: register with .register_get()
|
||||
// Rhai passes &mut User to these
|
||||
pub fn get_id_rhai(&mut self) -> INT { self.base_data.id as INT }
|
||||
pub fn get_username_rhai(&mut self) -> String { self.username.clone() }
|
||||
pub fn get_email_rhai(&mut self) -> String { self.email.clone() }
|
||||
pub fn get_full_name_rhai(&mut self) -> String { self.full_name.clone() }
|
||||
pub fn get_is_active_rhai(&mut self) -> bool { self.is_active }
|
||||
pub fn get_comment_ids_rhai(&mut self) -> Vec<u32> { self.base_data.comment_ids.clone() }
|
||||
}
|
||||
|
||||
|
||||
// --- Comment Struct and Methods (Adapted for Rhai) ---
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, CustomType)]
|
||||
pub struct Comment {
|
||||
pub id: INT,
|
||||
pub user_id: INT, // Assuming comments are linked to users by ID
|
||||
pub content: String,
|
||||
}
|
||||
|
||||
impl Comment {
|
||||
pub fn comment_builder(id: INT) -> Self {
|
||||
Self {
|
||||
id,
|
||||
user_id: 0, // Default
|
||||
content: String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
// Fluent setters
|
||||
pub fn user_id(mut self, user_id: INT) -> Self {
|
||||
self.user_id = user_id;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn content(mut self, content: String) -> Self {
|
||||
self.content = content;
|
||||
self
|
||||
}
|
||||
|
||||
// Getters for Rhai
|
||||
pub fn get_id_rhai(&mut self) -> INT { self.id }
|
||||
pub fn get_user_id_rhai(&mut self) -> INT { self.user_id }
|
||||
pub fn get_content_rhai(&mut self) -> String { self.content.clone() }
|
||||
}
|
||||
|
||||
// --- Mock Database ---
|
||||
#[derive(Debug, Clone, Default)]
|
||||
struct DbState {
|
||||
users: HashMap<INT, User>,
|
||||
comments: HashMap<INT, Comment>,
|
||||
}
|
||||
|
||||
type OurDB = Arc<Mutex<DbState>>;
|
||||
|
||||
fn set_user(db_arc: OurDB, user: User) {
|
||||
let mut db = db_arc.lock().unwrap();
|
||||
db.users.insert(user.base_data.id as INT, user);
|
||||
}
|
||||
|
||||
fn get_user_by_id(db_arc: OurDB, id: INT) -> Option<User> {
|
||||
let db = db_arc.lock().unwrap();
|
||||
db.users.get(&id).cloned()
|
||||
}
|
||||
|
||||
fn get_all_users(db_arc: OurDB) -> Vec<User> {
|
||||
let db = db_arc.lock().unwrap();
|
||||
db.users.values().cloned().collect()
|
||||
}
|
||||
|
||||
fn delete_user_by_id(db_arc: OurDB, id: INT) {
|
||||
let mut db = db_arc.lock().unwrap();
|
||||
db.users.remove(&id);
|
||||
}
|
||||
|
||||
fn set_comment(db_arc: OurDB, comment: Comment) {
|
||||
let mut db = db_arc.lock().unwrap();
|
||||
db.comments.insert(comment.id, comment);
|
||||
}
|
||||
|
||||
fn get_comment_by_id(db_arc: OurDB, id: INT) -> Option<Comment> {
|
||||
let db = db_arc.lock().unwrap();
|
||||
db.comments.get(&id).cloned()
|
||||
}
|
||||
|
||||
fn get_users_by_activity_status_optional(db_arc: OurDB, is_active_filter: bool) -> Option<Vec<User>> {
|
||||
let db = db_arc.lock().unwrap();
|
||||
let users: Vec<User> = db.users.values()
|
||||
.filter(|u| u.is_active == is_active_filter)
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
if users.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(users)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut engine = Engine::new();
|
||||
|
||||
let db_instance: OurDB = Arc::new(Mutex::new(DbState::default()));
|
||||
|
||||
// Register User type and its methods/getters/setters
|
||||
engine
|
||||
.register_type_with_name::<User>("User")
|
||||
// Fluent methods - these are registered as functions that take User and return User
|
||||
.register_fn("user_builder", User::user_builder)
|
||||
.register_fn("username", User::username)
|
||||
.register_fn("email", User::email)
|
||||
.register_fn("full_name", User::full_name)
|
||||
.register_fn("is_active", User::is_active) // This is the fluent setter
|
||||
.register_fn("add_comment", User::add_comment)
|
||||
.register_fn("activate", User::activate)
|
||||
.register_fn("deactivate", User::deactivate)
|
||||
// Getters for direct field-like access: user.id, user.username etc.
|
||||
.register_get("id", User::get_id_rhai)
|
||||
.register_get("username", User::get_username_rhai)
|
||||
.register_get("email", User::get_email_rhai)
|
||||
.register_get("full_name", User::get_full_name_rhai)
|
||||
.register_get("is_active", User::get_is_active_rhai) // This is the getter for direct field access
|
||||
.register_get("comment_ids", User::get_comment_ids_rhai);
|
||||
|
||||
// Register Comment type and its methods/getters/setters
|
||||
engine
|
||||
.register_type_with_name::<Comment>("Comment")
|
||||
.register_fn("comment_builder", Comment::comment_builder)
|
||||
.register_fn("user_id", Comment::user_id)
|
||||
.register_fn("content", Comment::content)
|
||||
.register_get("id", Comment::get_id_rhai)
|
||||
.register_get("user_id", Comment::get_user_id_rhai)
|
||||
.register_get("content", Comment::get_content_rhai);
|
||||
|
||||
// DB functions - now directly registered
|
||||
let db_clone_for_get_db = db_instance.clone();
|
||||
engine.register_fn("get_db", move || db_clone_for_get_db.clone());
|
||||
|
||||
let db_clone_for_set_user = db_instance.clone();
|
||||
engine.register_fn("set_user", move |user: User| set_user(db_clone_for_set_user.clone(), user));
|
||||
|
||||
let db_clone_for_get_user_by_id = db_instance.clone();
|
||||
engine.register_fn("get_user_by_id", move |id: INT| {
|
||||
wrap_option_return!(get_user_by_id, OurDB, INT => User)(db_clone_for_get_user_by_id.clone(), id)
|
||||
});
|
||||
|
||||
let db_clone_for_get_all_users = db_instance.clone();
|
||||
engine.register_fn(
|
||||
"get_all_users",
|
||||
move || {
|
||||
(wrap_vec_return!(get_all_users, OurDB => User))(db_clone_for_get_all_users.clone())
|
||||
}
|
||||
);
|
||||
|
||||
let db_clone_for_delete_user = db_instance.clone();
|
||||
engine.register_fn("delete_user_by_id", move |id: INT| delete_user_by_id(db_clone_for_delete_user.clone(), id));
|
||||
|
||||
let db_clone_for_set_comment = db_instance.clone();
|
||||
engine.register_fn("set_comment", move |comment: Comment| set_comment(db_clone_for_set_comment.clone(), comment));
|
||||
|
||||
let db_clone_for_get_comment_by_id = db_instance.clone();
|
||||
engine.register_fn("get_comment_by_id", move |id: INT| {
|
||||
wrap_option_return!(get_comment_by_id, OurDB, INT => Comment)(db_clone_for_get_comment_by_id.clone(), id)
|
||||
});
|
||||
|
||||
let db_clone_for_optional_vec = db_instance.clone();
|
||||
engine.register_fn(
|
||||
"get_users_by_activity_status_optional",
|
||||
move |is_active_filter: bool| {
|
||||
(wrap_option_vec_return!(get_users_by_activity_status_optional, OurDB, bool => User))(
|
||||
db_clone_for_optional_vec.clone(),
|
||||
is_active_filter
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
engine.register_fn("println", |s: &str| println!("{}", s));
|
||||
engine.register_fn("print", |s: &str| print!("{}", s));
|
||||
|
||||
let script_path = Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("examples")
|
||||
.join("user_script.rhai");
|
||||
|
||||
println!("Loading Rhai script from: {}", script_path.display());
|
||||
|
||||
match engine.eval_file::<()>(script_path) {
|
||||
Ok(_) => println!("Script executed successfully"),
|
||||
Err(e) => eprintln!("Error executing script: {}\nAt: {:?}", e, e.position()),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
175
rhai_wrapper/examples/user_script.rhai
Normal file
175
rhai_wrapper/examples/user_script.rhai
Normal file
@@ -0,0 +1,175 @@
|
||||
// Hero Models - Rhai Example Script
|
||||
println("Hero Models - Rhai Usage Example");
|
||||
println("================================");
|
||||
|
||||
// Get the DB instance
|
||||
let db = get_db();
|
||||
|
||||
// Create a new user using the builder pattern
|
||||
println("Creating users...");
|
||||
|
||||
// Create user 1
|
||||
let user1 = user_builder(1)
|
||||
.username("johndoe")
|
||||
.email("john.doe@example.com")
|
||||
.full_name("John Doe")
|
||||
.is_active(false);
|
||||
set_user(user1);
|
||||
|
||||
// Create user 2
|
||||
let user2 = user_builder(2)
|
||||
.username("janesmith")
|
||||
.email("jane.smith@example.com")
|
||||
.full_name("Jane Smith")
|
||||
.is_active(true);
|
||||
set_user(user2);
|
||||
|
||||
// Create user 3
|
||||
let user3 = user_builder(3)
|
||||
.username("willism")
|
||||
.email("willis.masters@example.com")
|
||||
.full_name("Willis Masters")
|
||||
.is_active(true);
|
||||
set_user(user3);
|
||||
|
||||
// Create user 4
|
||||
let user4 = user_builder(4)
|
||||
.username("carrols")
|
||||
.email("carrol.smith@example.com")
|
||||
.full_name("Carrol Smith")
|
||||
.is_active(false);
|
||||
|
||||
set_user(user4);
|
||||
|
||||
// Get user by ID
|
||||
println("\nRetrieving user by ID...");
|
||||
let retrieved_user = get_user_by_id(1);
|
||||
if retrieved_user != () { // In Rhai, functions returning Option<T> yield () for None
|
||||
println("Found user: " + retrieved_user.full_name + " (ID: " + retrieved_user.id + ")");
|
||||
println("Username: " + retrieved_user.username);
|
||||
println("Email: " + retrieved_user.email);
|
||||
println("Active: " + retrieved_user.is_active);
|
||||
} else {
|
||||
println("User not found");
|
||||
}
|
||||
|
||||
// Get users by active status
|
||||
println("\nRetrieving active users...");
|
||||
let all_users_for_active_check = get_all_users();
|
||||
let active_users = [];
|
||||
|
||||
// Filter active users
|
||||
for user_item in all_users_for_active_check {
|
||||
if user_item.is_active == true {
|
||||
active_users.push(user_item);
|
||||
}
|
||||
}
|
||||
|
||||
println("Found " + active_users.len() + " active users:");
|
||||
for user_item in active_users {
|
||||
println("- " + user_item.full_name + " (ID: " + user_item.id + ")");
|
||||
}
|
||||
|
||||
// Delete a user
|
||||
println("\nDeleting user...");
|
||||
delete_user_by_id(2);
|
||||
|
||||
// Get active users again
|
||||
println("\nRetrieving active users after deletion...");
|
||||
let all_users_after_delete = get_all_users();
|
||||
let active_users_after_delete = [];
|
||||
|
||||
// Filter active users
|
||||
for user_item in all_users_after_delete {
|
||||
if user_item.is_active == true {
|
||||
active_users_after_delete.push(user_item);
|
||||
}
|
||||
}
|
||||
|
||||
println("Found " + active_users_after_delete.len() + " active users:");
|
||||
for user_item in active_users_after_delete {
|
||||
println("- " + user_item.full_name + " (ID: " + user_item.id + ")");
|
||||
}
|
||||
|
||||
// Get inactive users
|
||||
println("\nRetrieving inactive users...");
|
||||
let all_users_for_inactive_check = get_all_users();
|
||||
let inactive_users = [];
|
||||
|
||||
// Filter inactive users
|
||||
for user_item in all_users_for_inactive_check {
|
||||
if user_item.is_active == false {
|
||||
inactive_users.push(user_item);
|
||||
}
|
||||
}
|
||||
|
||||
println("Found " + inactive_users.len() + " inactive users:");
|
||||
for user_item in inactive_users {
|
||||
println("- " + user_item.full_name + " (ID: " + user_item.id + ")");
|
||||
}
|
||||
|
||||
// Create a comment for user 1
|
||||
println("\nCreating a comment...");
|
||||
let comment1 = comment_builder(5)
|
||||
.user_id(1)
|
||||
.content("This is a comment on the user");
|
||||
set_comment(comment1);
|
||||
|
||||
// Get the comment
|
||||
println("\nRetrieving comment...");
|
||||
let retrieved_comment = get_comment_by_id(5);
|
||||
if retrieved_comment != () { // In Rhai, functions returning Option<T> yield () for None
|
||||
println("Found comment: " + retrieved_comment.content);
|
||||
println("Comment ID: " + retrieved_comment.id);
|
||||
println("User ID: " + retrieved_comment.user_id);
|
||||
} else {
|
||||
println("Comment not found");
|
||||
}
|
||||
|
||||
println("\nRetrieving optional active users (should be Some(Array) or Unit)...");
|
||||
let optional_active_users = get_users_by_activity_status_optional(true);
|
||||
if optional_active_users == () { // Check for unit (None)
|
||||
println("No active users found (returned unit).");
|
||||
} else {
|
||||
println("Found optional active users:");
|
||||
for user in optional_active_users {
|
||||
println("- " + user.full_name + " (ID: " + user.id + ")");
|
||||
}
|
||||
}
|
||||
|
||||
println("\nRetrieving optional inactive users (should be Some(Array) or Unit)...");
|
||||
let optional_inactive_users = get_users_by_activity_status_optional(false);
|
||||
if optional_inactive_users == () { // Check for unit (None)
|
||||
println("No inactive users found (returned unit).");
|
||||
} else {
|
||||
println("Found optional inactive users:");
|
||||
for user in optional_inactive_users {
|
||||
println("- " + user.full_name + " (ID: " + user.id + ")");
|
||||
}
|
||||
}
|
||||
|
||||
// To specifically test the None case from our Rust logic (empty vec for a status returns None)
|
||||
println("\nTesting None case for optional vector retrieval...");
|
||||
println("Deleting all users to ensure empty states...");
|
||||
let all_users_before_delete_all = get_all_users();
|
||||
for user_to_delete in all_users_before_delete_all {
|
||||
delete_user_by_id(user_to_delete.id);
|
||||
}
|
||||
|
||||
let optional_active_after_delete_all = get_users_by_activity_status_optional(true);
|
||||
if optional_active_after_delete_all == () {
|
||||
println("Correctly received unit for active users after deleting all.");
|
||||
} else {
|
||||
println("ERROR: Expected unit for active users after deleting all, but got an array.");
|
||||
print("Value received: " + optional_active_after_delete_all);
|
||||
}
|
||||
|
||||
let optional_inactive_after_delete_all = get_users_by_activity_status_optional(false);
|
||||
if optional_inactive_after_delete_all == () {
|
||||
println("Correctly received unit for inactive users after deleting all.");
|
||||
} else {
|
||||
println("ERROR: Expected unit for inactive users after deleting all, but got an array.");
|
||||
print("Value received: " + optional_inactive_after_delete_all);
|
||||
}
|
||||
|
||||
println("\nRhai example completed successfully!");
|
Reference in New Issue
Block a user