Implemented features: - High-performance Rust extension with Redis persistence - Actor/player management with loadout, position, and state tracking - Banking system with deposit, withdraw, and transfer operations - Physical and virtual garage/locker systems for vehicle and equipment storage - Organization management with member tracking and permissions - Client-side UI with React-like state management - Server-side event-driven architecture with CBA Events - Security: Self-transfer prevention at multiple layers - Logging system with per-module log files - ICOM module for inter-server communication Co-Authored-By: Warp <agent@warp.dev>
70 lines
2.7 KiB
Rust
70 lines
2.7 KiB
Rust
/// Redis client abstraction for dependency injection
|
|
pub trait RedisClient: Send + Sync {
|
|
// Hash operations
|
|
fn hash_mset(&self, key: String, fields: Vec<(String, String)>) -> Result<(), String>;
|
|
fn hash_get_all(&self, key: String) -> Result<String, String>;
|
|
fn hash_get(&self, key: String, field: String) -> Result<String, String>;
|
|
fn hash_del(&self, key: String, field: String) -> Result<(), String>;
|
|
|
|
// List operations
|
|
fn list_rpush(&self, key: String, value: String) -> Result<(), String>;
|
|
fn list_range(&self, key: String, start: isize, end: isize) -> Result<Vec<String>, String>;
|
|
fn list_del(&self, key: String, count: isize, value: String) -> Result<(), String>;
|
|
|
|
// Set operations
|
|
fn set_add(&self, key: String, member: String) -> Result<(), String>;
|
|
fn set_members(&self, key: String) -> Result<Vec<String>, String>;
|
|
fn set_del(&self, key: String, member: String) -> Result<(), String>;
|
|
|
|
// Common operations
|
|
fn get_key(&self, key: String) -> Result<String, String>;
|
|
fn set_key(&self, key: String, value: String) -> Result<(), String>;
|
|
fn key_exists(&self, key: String) -> Result<bool, String>;
|
|
fn delete_key(&self, key: String) -> Result<(), String>;
|
|
}
|
|
|
|
/// Converts a JSON value to a Redis-compatible string format.
|
|
pub fn parse_json_value(value: &serde_json::Value) -> String {
|
|
let wrapped = serde_json::Value::Array(vec![value.clone()]);
|
|
wrapped.to_string()
|
|
}
|
|
|
|
/// Converts a Redis string value back to a JSON value with intelligent type detection.
|
|
pub fn parse_redis_value(value: &str) -> serde_json::Value {
|
|
// Handle empty values
|
|
if value.is_empty() {
|
|
return serde_json::Value::Null;
|
|
}
|
|
|
|
// Try to parse as JSON first
|
|
if let Ok(json_val) = serde_json::from_str(value) {
|
|
// Special handling for single-element arrays (unwrap them)
|
|
if let serde_json::Value::Array(arr) = &json_val {
|
|
if arr.len() == 1 {
|
|
return arr[0].clone();
|
|
}
|
|
}
|
|
return json_val;
|
|
}
|
|
|
|
// Try to parse as integer
|
|
if let Ok(int_val) = value.parse::<i64>() {
|
|
return serde_json::Value::Number(serde_json::Number::from(int_val));
|
|
}
|
|
|
|
// Try to parse as float
|
|
if let Ok(float_val) = value.parse::<f64>() {
|
|
if let Some(num) = serde_json::Number::from_f64(float_val) {
|
|
return serde_json::Value::Number(num);
|
|
}
|
|
}
|
|
|
|
// Try to parse as boolean (case-insensitive)
|
|
match value.to_lowercase().as_str() {
|
|
"true" => serde_json::Value::Bool(true),
|
|
"false" => serde_json::Value::Bool(false),
|
|
// Default to string if no other type matches
|
|
_ => serde_json::Value::String(value.to_string()),
|
|
}
|
|
}
|