Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
June 15, 2021 12:24 am GMT

A Command Line Key-Value Data Store using the Rust Programming Language.

Prelude

Rust is an imperative, super fast, and type-safe programming language that empowers you a Software Engineer "to reach farther, to program with confidence in a wider variety of domains than you did before." No wonder it has consistently maintained its deserved spot as the most loved programming language for half a decade!

What we are building

Using barebone rust code, we will be building a simple command line key-value data store like Redis. It should take in two command line arguments and assign the first as the key while the second, value.

If installed on your machine, it can be used as follows:

(sirneij@sirneij)-[~/Documents/Projects/rust-kvstore]$[sirneij@sirneij rust-kvstore]$ rust-kvstore needle haystack

This should create a file, aptly named kv.db. It's content can then be read:

(sirneij@sirneij)-[~/Documents/Projects/rust-kvstore]$[sirneij@sirneij rust-kvstore]$ cat kv.db

Whose output should look like:

        File: kv.db   1    needle  haystack

However, if you have the source files, you can simply build and run it using:

(sirneij@sirneij)-[~/Documents/Projects/rust-kvstore]$[sirneij@sirneij rust-kvstore]$ cargo run needle haystack

This is simply for learning sake and no other motive is intended.

DECLAIMER

This example is based off of a two-part tutorial anchored by the beloved Ryan Levick. The only significant additions are: the use of a Vec<String> instead of Iterator<Item = String>; fixing this bug

thread 'main' panicked at 'Corrupt database: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/main.rs:12:40note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


by checking if kv.db already exists and if not create it using Rust's PathBuf standard library; using a more efficient file reader; and using split_once() instead of rsplit() among others.
It is highly recommended to check out the awesome livestreams on youtube. I must confess, it was a total tear down and dissection.

Assumptions

It is assumed that you have read The Rust book to some extent or have checked out the awesome livestreams on youtube by Ryan Levick.

Source code

As usual, you can get the full version of the source files for this article on github. Just clone it:

(sirneij@sirneij)-[~/Documents/Projects]$[sirneij@sirneij Projects]$  git clone https://github.com/Sirneij/rust-kvstore.git

and open it in your favourite text editor, mine is vs code.

(sirneij@sirneij)-[~/Documents/Projects]$[sirneij@sirneij Projects]$ cd rust-kvstore && code .

Proper implementation

Going by the assumptions made above, I will only point out some of my inputs.

  • Taking arguments as vectors:

Since our little project wants to get two command line arguments, Rust provides a function args() which can be found in the std::env library. This function returns an iterator of the command line arguments. The .collect() converts the returned iterator into a vector. Its implementation for this project looks this way:

fn main(){    let args: Vec<String> = std::env::args().collect();    let key = &args[1];    let value = &args[2];}

It should be noted that &args[0] gives the path to our executable which in this case should be "target/debug/rust-kvstore". You can see what is in args by printing it to the console using println!() macro:

fn main(){    let args: Vec<String> = std::env::args().collect();    println!("{:?}", args);    let key = &args[1];    let value = &args[2];}

You should see something like:

["target/debug/rust-kvstore", "needle", "haystack"]

if you pass needle haystack as arguments using cargo run like so:

(sirneij@sirneij)-[~/Documents/Projects/rust-kvstore]$[sirneij@sirneij rust-kvstore]$ cargo run needle haystack

Since we are only concerned with arguments we passed, which starts from &args[1], we overlooked &args[0].

  • Fixing "No such file or directory" bug:If kv.db is not manually created or not present at the start of the program's usage, an error of this form will surface:
thread 'main' panicked at 'Corrupt database: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/main.rs:12:40note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

To fix this, we need to check whether or not kv.db has been created. If not create it on the fly. To accomplish this, we use this awesome std::path::PathBuf library in our "constructor", new().

impl Database {   fn new() -> Result<Database, std::io::Error> {        ...        let mut contents = String::new();        let path = PathBuf::from("kv.db");        if path.exists() {            let file = std::fs::File::open(path)?;            let mut buf_reader = std::io::BufReader::new(file);            buf_reader.read_to_string(&mut contents)?;        } else {            std::fs::File::create("kv.db")?;        }        ...   }}
  • Using the more efficient std::io::BufReader
    It can also be seen in the snippet above that instead of using the std::read_to_string, we opted for the more efficient std::io::BufReader::new(file);

  • split_once() implemented:
    When Ryan was livestreaming, split_once() was only available in the nightly version of Rust so he opted for rsplit(). However, I think it is stable now and the full implementation is shown as follows:

     ...     for line in contents.lines() {            let (key, value) = line.split_once("").expect("Corrupt database");            map.insert(key.to_string(), value.to_string());        }     ...

That's it! Nifty and awesome. To build the project from scratch, code along with Ryan Levick..

Kindly drop your comments, reactions and suggestions. Make me a better writer.

References

Attributions


Original Link: https://dev.to/sirneij/a-command-line-key-value-data-store-using-the-rust-programming-language-33b6

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To