1extern crate resp_async;
2extern crate tokio;
3
4use std::env;
5use std::sync::Mutex;
6
7use bytes::Bytes;
8use tokio::signal;
9
10use resp_async::error::Result;
11use resp_async::{Cmd, Router, Server, State, Value};
12
13#[derive(Default)]
14struct AppState {
15 history: Mutex<Vec<Value>>,
16}
17
18async fn history(State(state): State<AppState>, Cmd(cmd): Cmd) -> Value {
19 if cmd.name_upper.as_ref() == b"COMMAND" {
20 if let Some(Value::Bulk(arg)) = cmd.args.get(0) {
21 if arg.as_ref() == b"DOCS" {
22 return Value::Array(Vec::new());
23 }
24 }
25 }
26
27 let mut history = state.history.lock().unwrap();
28 let mut entry = Vec::with_capacity(1 + cmd.args.len());
29 entry.push(Value::Bulk(cmd.name));
30 entry.extend(cmd.args);
31 history.push(Value::Array(entry));
32 Value::Array(history.clone())
33}
34
35async fn ping() -> Value {
36 Value::Simple(Bytes::from_static(b"PONG"))
37}
38
39#[tokio::main]
40pub async fn main() -> Result<()> {
41 let addr = env::args()
42 .nth(1)
43 .unwrap_or_else(|| "0.0.0.0:6379".to_string());
44
45 let app = Router::from_state(AppState::default())
46 .route("HISTORY", history)
47 .route("COMMAND", history)
48 .route("PING", ping);
49
50 Server::bind(&addr)
51 .with_graceful_shutdown(async {
52 let _ = signal::ctrl_c().await;
53 })
54 .serve(app)
55 .await
56}