cli
This commit is contained in:
54
Cargo.lock
generated
54
Cargo.lock
generated
@@ -83,8 +83,10 @@ dependencies = [
|
|||||||
"bon",
|
"bon",
|
||||||
"bytes",
|
"bytes",
|
||||||
"byteyarn",
|
"byteyarn",
|
||||||
|
"clap",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"log",
|
"log",
|
||||||
|
"shell-words",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
@@ -177,6 +179,46 @@ version = "1.0.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
|
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]]
|
[[package]]
|
||||||
name = "colorchoice"
|
name = "colorchoice"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@@ -253,6 +295,12 @@ version = "0.31.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ident_case"
|
name = "ident_case"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
@@ -500,6 +548,12 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shell-words"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook-registry"
|
name = "signal-hook-registry"
|
||||||
version = "1.4.5"
|
version = "1.4.5"
|
||||||
|
|||||||
12
Cargo.toml
12
Cargo.toml
@@ -2,12 +2,24 @@
|
|||||||
name = "archive"
|
name = "archive"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
authors = ["409"]
|
||||||
|
default-run = "archive-server"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bon = "3.6.4"
|
bon = "3.6.4"
|
||||||
bytes = "1.10.1"
|
bytes = "1.10.1"
|
||||||
byteyarn = "0.5.1"
|
byteyarn = "0.5.1"
|
||||||
|
clap = { version = "4.5.40", features = ["derive"] }
|
||||||
env_logger = "0.11.8"
|
env_logger = "0.11.8"
|
||||||
log = "0.4.27"
|
log = "0.4.27"
|
||||||
|
shell-words = "1.1.0"
|
||||||
thiserror = "2.0.12"
|
thiserror = "2.0.12"
|
||||||
tokio = { version = "1.45.1", features = ["full"] }
|
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 archive::Result;
|
||||||
use errors::AppError;
|
use archive::config::ServerConfig;
|
||||||
use server::Server;
|
use archive::server::Server;
|
||||||
|
|
||||||
use tokio::{signal::ctrl_c, sync::oneshot};
|
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]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
env_logger::builder()
|
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