cli
This commit is contained in:
54
Cargo.lock
generated
54
Cargo.lock
generated
@@ -83,8 +83,10 @@ dependencies = [
|
||||
"bon",
|
||||
"bytes",
|
||||
"byteyarn",
|
||||
"clap",
|
||||
"env_logger",
|
||||
"log",
|
||||
"shell-words",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
]
|
||||
@@ -177,6 +179,46 @@ version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.4"
|
||||
@@ -253,6 +295,12 @@ version = "0.31.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
@@ -500,6 +548,12 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shell-words"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.5"
|
||||
|
||||
12
Cargo.toml
12
Cargo.toml
@@ -2,12 +2,24 @@
|
||||
name = "archive"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
authors = ["409"]
|
||||
default-run = "archive-server"
|
||||
|
||||
[dependencies]
|
||||
bon = "3.6.4"
|
||||
bytes = "1.10.1"
|
||||
byteyarn = "0.5.1"
|
||||
clap = { version = "4.5.40", features = ["derive"] }
|
||||
env_logger = "0.11.8"
|
||||
log = "0.4.27"
|
||||
shell-words = "1.1.0"
|
||||
thiserror = "2.0.12"
|
||||
tokio = { version = "1.45.1", features = ["full"] }
|
||||
|
||||
[[bin]]
|
||||
name = "archive-server"
|
||||
path = "src/bin/server.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "archive-cli"
|
||||
path = "src/bin/cli.rs"
|
||||
|
||||
123
src/bin/cli.rs
Normal file
123
src/bin/cli.rs
Normal file
@@ -0,0 +1,123 @@
|
||||
use std::io::{Write as _, stdin};
|
||||
|
||||
use archive::{Result, client::Client};
|
||||
use clap::Parser;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[command(version, about, long_about = None)]
|
||||
struct Args {
|
||||
#[arg(long, default_value = "127.0.0.1")]
|
||||
host: String,
|
||||
#[arg(short, long, default_value_t = 6171)]
|
||||
port: u16,
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[command(help_template = "{subcommands}")]
|
||||
enum Commands {
|
||||
Get {
|
||||
key: String,
|
||||
},
|
||||
Set {
|
||||
key: String,
|
||||
value: String,
|
||||
expiration: Option<u64>,
|
||||
},
|
||||
Delete {
|
||||
key: String,
|
||||
},
|
||||
Has {
|
||||
key: String,
|
||||
},
|
||||
Ttl {
|
||||
key: String,
|
||||
},
|
||||
Expire {
|
||||
key: String,
|
||||
seconds: u64,
|
||||
},
|
||||
Persist {
|
||||
key: String,
|
||||
},
|
||||
#[command(aliases = &["exit", "q"])]
|
||||
Quit,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let args = Args::parse();
|
||||
|
||||
let mut client = Client::new(&format!("{}:{}", args.host, args.port)).await?;
|
||||
|
||||
print_welcome();
|
||||
|
||||
let stdin = stdin();
|
||||
let mut input = String::new();
|
||||
|
||||
loop {
|
||||
input.clear();
|
||||
print!("> ");
|
||||
std::io::stdout().flush()?;
|
||||
stdin.read_line(&mut input)?;
|
||||
|
||||
let Ok(mut words) = shell_words::split(&input) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
words.insert(0, "".into());
|
||||
|
||||
let command = match Commands::try_parse_from(words.clone()) {
|
||||
Ok(command) => command,
|
||||
Err(e) => {
|
||||
println!("{}", e.render());
|
||||
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
match command {
|
||||
Commands::Get { key } => {
|
||||
let value = client.get(&key).await?;
|
||||
println!("{value:?}");
|
||||
}
|
||||
Commands::Set {
|
||||
key,
|
||||
value,
|
||||
expiration,
|
||||
} => {
|
||||
client.set(&key, value.as_bytes(), expiration).await?;
|
||||
println!("1");
|
||||
}
|
||||
Commands::Delete { key } => {
|
||||
let value = client.delete(&key).await?;
|
||||
println!("{value:?}");
|
||||
}
|
||||
Commands::Has { key } => {
|
||||
let value = client.has(&key).await?;
|
||||
println!("{value:?}");
|
||||
}
|
||||
Commands::Ttl { key } => {
|
||||
let value = client.ttl(&key).await?;
|
||||
println!("{value:?}");
|
||||
}
|
||||
Commands::Expire { key, seconds } => {
|
||||
let value = client.expire(&key, seconds).await?;
|
||||
println!("{value:?}");
|
||||
}
|
||||
Commands::Persist { key } => {
|
||||
let value = client.persist(&key).await?;
|
||||
println!("{value:?}");
|
||||
}
|
||||
Commands::Quit => break,
|
||||
}
|
||||
}
|
||||
|
||||
println!("{input}");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_welcome() {
|
||||
let version = env!("CARGO_PKG_VERSION");
|
||||
println!("archive-cli {version}");
|
||||
}
|
||||
@@ -1,22 +1,9 @@
|
||||
use config::ServerConfig;
|
||||
use errors::AppError;
|
||||
use server::Server;
|
||||
use archive::Result;
|
||||
use archive::config::ServerConfig;
|
||||
use archive::server::Server;
|
||||
|
||||
use tokio::{signal::ctrl_c, sync::oneshot};
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests;
|
||||
|
||||
pub mod client;
|
||||
pub mod commands;
|
||||
pub mod config;
|
||||
pub mod connection;
|
||||
pub mod database;
|
||||
pub mod errors;
|
||||
pub mod handler;
|
||||
pub mod server;
|
||||
|
||||
pub type Result<T> = std::result::Result<T, AppError>;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
env_logger::builder()
|
||||
15
src/lib.rs
Normal file
15
src/lib.rs
Normal file
@@ -0,0 +1,15 @@
|
||||
use errors::AppError;
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests;
|
||||
|
||||
pub mod client;
|
||||
pub mod commands;
|
||||
pub mod config;
|
||||
pub mod connection;
|
||||
pub mod database;
|
||||
pub mod errors;
|
||||
pub mod handler;
|
||||
pub mod server;
|
||||
|
||||
pub type Result<T> = std::result::Result<T, AppError>;
|
||||
Reference in New Issue
Block a user