From 5954774afdc05e16a3f14adefed6b87c2f32453e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=93=D1=80=D0=B8=D0=B3=D0=BE=D1=80=D0=B8=D0=B9=20=D0=A1?= =?UTF-8?q?=D0=B0=D1=84=D1=80=D0=BE=D0=BD=D0=BE=D0=B2?= Date: Tue, 1 Jul 2025 19:39:50 +0000 Subject: [PATCH] Update futriix-cli/src/main.rs --- futriix-cli/src/main.rs | 100 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 93 insertions(+), 7 deletions(-) diff --git a/futriix-cli/src/main.rs b/futriix-cli/src/main.rs index e53fce1..c33f207 100644 --- a/futriix-cli/src/main.rs +++ b/futriix-cli/src/main.rs @@ -1,9 +1,7 @@ use colored::Colorize; use rustyline::Editor; use rustyline::error::ReadlineError; -use serde::{Deserialize, Serialize}; use serde_json; -use std::error::Error; use std::fs; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::TcpStream; @@ -25,12 +23,22 @@ mod server { CreateIndex { field: String }, DropIndex { field: String }, SysExec { script_name: String }, + ReplicationEnable, + ReplicationDisable, + ReplicationAddPeer { addr: String }, + ReplicationRemovePeer { addr: String }, + ReplicationStatus, } #[derive(Debug, Serialize, Deserialize)] pub enum Response { Success(Option), Error(String), + ReplicationStatus { + enabled: bool, + peers: Vec, + last_sync: u128, + }, } } @@ -64,8 +72,9 @@ async fn send_command(cmd: Command) -> Result Result<(), Box> { println!(); - println!("{}", "Futriix CLI Client".bright_cyan()); + println!("{}", "Futriix CLI Client".bold().bright_cyan()); println!("Type 'help' for available commands"); + println!(); let mut rl = Editor::<()>::new()?; if rl.load_history("futriix-history.txt").is_err() { @@ -74,7 +83,7 @@ async fn main() -> Result<(), Box> { } loop { - let readline = rl.readline("futriix> "); + let readline = rl.readline(&"futriix:~> ".bright_cyan()); match readline { Ok(line) => { rl.add_history_entry(&line); @@ -99,6 +108,7 @@ async fn main() -> Result<(), Box> { println!(); }, Ok(Response::Error(e)) => println!("{}", e.bold().red()), + Ok(Response::ReplicationStatus { .. }) => println!("{}", "Unexpected response type".red()), Err(e) => println!("{}: {}", "Connection error".red(), e), }, Err(e) => println!("{}: {}", "Invalid JSON".red(), e), @@ -120,6 +130,7 @@ async fn main() -> Result<(), Box> { println!(); }, Ok(Response::Error(e)) => println!("{}", e.bold().red()), + Ok(Response::ReplicationStatus { .. }) => println!("{}", "Unexpected response type".red()), Err(e) => println!("{}: {}", "Connection error".red(), e), } }, @@ -137,6 +148,7 @@ async fn main() -> Result<(), Box> { println!(); }, Ok(Response::Error(e)) => println!("{}", e.bold().red()), + Ok(Response::ReplicationStatus { .. }) => println!("{}", "Unexpected response type".red()), Err(e) => println!("{}: {}", "Connection error".red(), e), }, Err(e) => println!("{}: {}", "Invalid JSON".red(), e), @@ -154,6 +166,7 @@ async fn main() -> Result<(), Box> { println!(); }, Ok(Response::Error(e)) => println!("{}", e.bold().red()), + Ok(Response::ReplicationStatus { .. }) => println!("{}", "Unexpected response type".red()), Err(e) => println!("{}: {}", "Connection error".red(), e), } }, @@ -164,6 +177,7 @@ async fn main() -> Result<(), Box> { println!(); }, Ok(Response::Error(e)) => println!("{}", e.bold().red()), + Ok(Response::ReplicationStatus { .. }) => println!("{}", "Unexpected response type".red()), Err(e) => println!("{}: {}", "Connection error".red(), e), } }, @@ -174,6 +188,7 @@ async fn main() -> Result<(), Box> { println!(); }, Ok(Response::Error(e)) => println!("{}", e.bold().red()), + Ok(Response::ReplicationStatus { .. }) => println!("{}", "Unexpected response type".red()), Err(e) => println!("{}: {}", "Connection error".red(), e), } }, @@ -184,6 +199,7 @@ async fn main() -> Result<(), Box> { println!(); }, Ok(Response::Error(e)) => println!("{}", e.bold().red()), + Ok(Response::ReplicationStatus { .. }) => println!("{}", "Unexpected response type".red()), Err(e) => println!("{}: {}", "Connection error".red(), e), } }, @@ -193,12 +209,13 @@ async fn main() -> Result<(), Box> { continue; } let field = parts[1].to_string(); - match send_command(Command::CreateIndex { field }).await { + match send_command(Command::CreateIndex { field: field.clone() }).await { Ok(Response::Success(_)) => { - println!("{}", "Index created".bright_green()); + println!("{}", format!("Index created on field '{}'", field).bright_green()); println!(); }, Ok(Response::Error(e)) => println!("{}", e.bold().red()), + Ok(Response::ReplicationStatus { .. }) => println!("{}", "Unexpected response type".red()), Err(e) => println!("{}: {}", "Connection error".red(), e), } }, @@ -214,6 +231,7 @@ async fn main() -> Result<(), Box> { println!(); }, Ok(Response::Error(e)) => println!("{}", e.bold().red()), + Ok(Response::ReplicationStatus { .. }) => println!("{}", "Unexpected response type".red()), Err(e) => println!("{}: {}", "Connection error".red(), e), } }, @@ -234,11 +252,75 @@ async fn main() -> Result<(), Box> { println!(); }, Ok(Response::Error(e)) => println!("{}", e.bold().red()), + Ok(Response::ReplicationStatus { .. }) => println!("{}", "Unexpected response type".red()), Err(e) => println!("{}: {}", "Connection error".red(), e), } }, + "replication" => { + if parts.len() < 2 { + println!("{}", "Usage: replication ".red()); + continue; + } + match parts[1].to_lowercase().as_str() { + "on" => { + match send_command(Command::ReplicationEnable).await { + Ok(Response::Success(_)) => println!("{}", "Replication enabled".bright_green()), + Ok(Response::Error(e)) => println!("{}", e.red()), + Ok(Response::ReplicationStatus { .. }) => println!("{}", "Unexpected response type".red()), + Err(e) => println!("{}: {}", "Connection error".red(), e), + } + } + "off" => { + match send_command(Command::ReplicationDisable).await { + Ok(Response::Success(_)) => println!("{}", "Replication disabled".bright_green()), + Ok(Response::Error(e)) => println!("{}", e.red()), + Ok(Response::ReplicationStatus { .. }) => println!("{}", "Unexpected response type".red()), + Err(e) => println!("{}: {}", "Connection error".red(), e), + } + } + "status" => { + match send_command(Command::ReplicationStatus).await { + Ok(Response::ReplicationStatus { enabled, peers, last_sync }) => { + println!("Status:"); + println!(" Enabled: {}", enabled); + println!(" Peers: {:?}", peers); + println!(" Last sync: {}", last_sync); + } + Ok(Response::Success(_)) => println!("{}", "Unexpected success response".red()), + Ok(Response::Error(e)) => println!("{}", e.red()), + Err(e) => println!("{}: {}", "Connection error".red(), e), + } + } + "add-peer" => { + if parts.len() < 3 { + println!("{}", "Usage: replication add-peer ".red()); + continue; + } + match send_command(Command::ReplicationAddPeer { addr: parts[2].to_string() }).await { + Ok(Response::Success(_)) => println!("{}", "Peer added".bright_green()), + Ok(Response::Error(e)) => println!("{}", e.red()), + Ok(Response::ReplicationStatus { .. }) => println!("{}", "Unexpected response type".red()), + Err(e) => println!("{}: {}", "Connection error".red(), e), + } + } + "remove-peer" => { + if parts.len() < 3 { + println!("{}", "Usage: replication remove-peer ".red()); + continue; + } + match send_command(Command::ReplicationRemovePeer { addr: parts[2].to_string() }).await { + Ok(Response::Success(_)) => println!("{}", "Peer removed".bright_green()), + Ok(Response::Error(e)) => println!("{}", e.red()), + Ok(Response::ReplicationStatus { .. }) => println!("{}", "Unexpected response type".red()), + Err(e) => println!("{}: {}", "Connection error".red(), e), + } + } + _ => println!("{}", "Unknown replication command".red()), + } + }, "help" => { - println!("Available commands:"); + println!(); + println!("{}", "Available commands:".bold()); println!(" insert (or i) - Insert data"); println!(" get (or g) - Get data"); println!(" update (or u) - Update data"); @@ -249,6 +331,10 @@ async fn main() -> Result<(), Box> { println!(" createindex - Create index"); println!(" dropindex - Drop index"); println!(" sysexec - Execute system script"); + println!(" replication on/off - Enable/disable replication"); + println!(" replication status - Show replication status"); + println!(" replication add-peer - Add replication peer"); + println!(" replication remove-peer - Remove replication peer"); println!(" exit (or quit) - Exit client"); println!(" help - Show this help"); println!();