Skip to content

Commit 85e9686

Browse files
committed
Restructure demos
- Move demo code into `examples/` folder - Restructure to enable generic use cases
1 parent 634f337 commit 85e9686

File tree

7 files changed

+204
-133
lines changed

7 files changed

+204
-133
lines changed

Cargo.toml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,6 @@ version = "0.1.0"
44
authors = ["Devdutt Shenoi <devdutt@outlook.in>"]
55
edition = "2018"
66

7-
[[bin]]
8-
name = "global"
9-
path = "src/global.rs"
10-
11-
[[bin]]
12-
name = "local"
13-
path = "src/local.rs"
14-
157
[dependencies]
168
tokio = { version = "0.2", features = ["full"] }
179
bytes = "1"

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ git clone https://github.com/vyuham/dstore
1717
```
1818
2. Run the server(ensure `cargo` is installed with [rustup](https://rustup.rs)):
1919
```bash
20-
cargo run --bin global
20+
cargo run --example global
2121
```
2222
Ensure the following is showing on the terminal:
2323
```
2424
Dstore server listening on 127.0.0.1:50051
2525
```
2626
3. On another terminal, start a client:
2727
```bash
28-
cargo run --bin local
28+
cargo run --example local
2929
```
3030
Ensure the following is showing on the terminal:
3131
```

examples/global.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
use dstore::global::Store;
2+
3+
#[tokio::main]
4+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
5+
let addr = "127.0.0.1:50051".parse().unwrap();
6+
7+
println!("Dstore server listening on {}", addr);
8+
Store::start(addr).await
9+
}

examples/local.rs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
use bytes::Bytes;
2+
use dstore::local::Store;
3+
use std::io;
4+
use std::io::{stdin, BufRead, Write};
5+
6+
pub struct REPL {
7+
store: Store,
8+
}
9+
10+
impl REPL {
11+
async fn new(store: Store) -> Self {
12+
Self { store }
13+
}
14+
15+
async fn parse_input(&mut self, cmd: String) -> Result<(), Box<dyn std::error::Error>> {
16+
// Meta commands start with `.`.
17+
if cmd.starts_with(".") {
18+
match MetaCmdResult::run(&cmd) {
19+
MetaCmdResult::Unrecognized => Ok(println!("db: meta command not found: {}", cmd)),
20+
MetaCmdResult::Success => Ok(()),
21+
}
22+
} else {
23+
let words = cmd.split(" ").collect::<Vec<&str>>();
24+
match words[0].to_lowercase().as_ref() {
25+
"set" | "put" | "insert" | "in" | "i" => {
26+
let key = words[1].to_string();
27+
let value = Bytes::from(words[2..].join(" "));
28+
if let Err(e) = self.store.insert(key, value).await {
29+
eprintln!("{}", e);
30+
}
31+
32+
Ok(())
33+
}
34+
"get" | "select" | "output" | "out" | "o" => {
35+
let key = words[1].to_string();
36+
match self.store.get(&key).await {
37+
Ok(value) => {
38+
println!("db: {} -> {}", key, String::from_utf8(value.to_vec())?)
39+
}
40+
Err(e) => eprintln!("{}", e),
41+
}
42+
43+
Ok(())
44+
}
45+
"del" | "delete" | "rem" | "remove" | "rm" | "d" => {
46+
// Removes only from local
47+
let key = words[1].to_string();
48+
Ok(self.store.remove(key))
49+
}
50+
_ => Ok(eprintln!("Unknown command!")),
51+
}
52+
}
53+
}
54+
}
55+
pub enum MetaCmdResult {
56+
Success,
57+
Unrecognized,
58+
}
59+
60+
impl MetaCmdResult {
61+
/// Execute Meta commands on the REPL.
62+
pub fn run(cmd: &String) -> Self {
63+
match cmd.as_ref() {
64+
".exit" => std::process::exit(0),
65+
".version" => {
66+
if let Some(ver) = option_env!("CARGO_PKG_VERSION") {
67+
println!("You are using KVDB v{}", ver);
68+
}
69+
Self::Success
70+
}
71+
_ => Self::Unrecognized,
72+
}
73+
}
74+
}
75+
76+
#[tokio::main]
77+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
78+
let client_addr = "http://127.0.0.1:50051".parse().unwrap();
79+
let local_store = Store::new(client_addr).await?;
80+
let mut repl = REPL::new(local_store).await;
81+
82+
print!("dstore v0.1.0\nThis is an experimental database, do contribute to further developments at https://github.com/vyuham/dstore. \nUse `.exit` to exit the repl\ndb > ");
83+
io::stdout().flush().expect("Error");
84+
85+
for cmd in stdin().lock().lines() {
86+
match cmd {
87+
Ok(cmd) => {
88+
repl.parse_input(cmd.trim().to_string()).await?;
89+
}
90+
Err(_) => eprint!("Error in reading command, exiting REPL."),
91+
}
92+
print!("db > ");
93+
io::stdout().flush().expect("Error");
94+
}
95+
96+
Ok(())
97+
}

src/global.rs

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,29 @@
1-
use std::collections::HashMap;
2-
use std::sync::{Arc, Mutex};
31
use bytes::Bytes;
2+
use std::sync::{Arc, Mutex};
3+
use std::{collections::HashMap, net::SocketAddr};
44
use tonic::{transport::Server, Request, Response, Status};
55

6-
use dstore::dstore_proto::dstore_server::{Dstore, DstoreServer};
7-
use dstore::dstore_proto::{GetArg, GetResult, SetArg, SetResult};
8-
struct Store {
6+
use crate::dstore_proto::dstore_server::{Dstore, DstoreServer};
7+
use crate::dstore_proto::{GetArg, GetResult, SetArg, SetResult};
8+
9+
pub struct Store {
910
db: Arc<Mutex<HashMap<String, Bytes>>>,
1011
}
1112

1213
impl Store {
13-
fn new(db: Arc<Mutex<HashMap<String, Bytes>>>) -> Self {
14-
Self { db }
14+
fn new() -> Self {
15+
Self {
16+
db: Arc::new(Mutex::new(HashMap::new())),
17+
}
18+
}
19+
20+
pub async fn start(addr: SocketAddr) -> Result<(), Box<dyn std::error::Error>> {
21+
Server::builder()
22+
.add_service(DstoreServer::new(Store::new()))
23+
.serve(addr)
24+
.await?;
25+
26+
Ok(())
1527
}
1628
}
1729

@@ -44,18 +56,3 @@ impl Dstore for Store {
4456
}
4557
}
4658
}
47-
48-
#[tokio::main]
49-
async fn main() -> Result<(), Box<dyn std::error::Error>> {
50-
let addr = "127.0.0.1:50051".parse().unwrap();
51-
let global_store = Arc::new(Mutex::new(HashMap::<String, Bytes>::new()));
52-
53-
println!("Dstore server listening on {}", addr);
54-
55-
Server::builder()
56-
.add_service(DstoreServer::new(Store::new(global_store)))
57-
.serve(addr)
58-
.await?;
59-
60-
Ok(())
61-
}

src/lib.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,28 @@
1+
use std::error::Error;
2+
use std::fmt;
3+
4+
#[derive(Debug)]
5+
pub struct DstoreError {
6+
msg: String,
7+
}
8+
9+
impl DstoreError {
10+
pub fn new(msg: String) -> Self {
11+
Self { msg }
12+
}
13+
}
14+
15+
impl fmt::Display for DstoreError {
16+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
17+
write!(f, "dstore error: {}", self.msg)
18+
}
19+
}
20+
21+
impl Error for DstoreError {}
22+
123
pub mod dstore_proto {
224
tonic::include_proto!("dstore");
325
}
26+
27+
pub mod global;
28+
pub mod local;

0 commit comments

Comments
 (0)