Skip to main content

history/
history.rs

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}