Learn Rust by Developing a Crypto Publisher CLI Application | by Sung Kim | Mar, 2022

Photograph by Charl Folscher on Unsplash

I all the time discover that when studying a programming language, it’s useful to simply begin creating an software from scratch, one step at a time. Even after you’ve got accomplished The Rust Programming Language e book, you could really feel at a loss on the place to begin.

This tutorial assumes you’ve got not less than glanced by means of the e book earlier than diving into creating a easy command-line interface (CLI) software to show crypto worth (e.g., Bitcoin worth in USD or BTC-USD).

Earlier than diving into an article, let’s get some housekeeping out of means first by offering a hyperlink to a GitHub repository the place all supply codes can be found => https://github.com/sungkim11/crypto-publisher. Additionally, I want to present you what software you may be creating utilizing Rust as proven beneath.

Coinbase Worth Knowledge REST API

We can be utilizing Coinbase REST API to get Bitcoin worth in US Greenback or BTC-USD (https://developers.coinbase.com/api/v2#data-endpoints).

To name Coinbase REST API, simply copy and paste the next URL to your browser:

https://api.coinbase.com/v2/prices/BTC-USD/spot

It ought to return or obtain response.json file with the next contents in JSON format for an instance, which offers each spot worth in addition to base-currency or BTC-USD.


"information":
"base":"BTC",
"forex":"USD",
"quantity":"40731.94"

Rust Crates

Earlier than we begin creating the appliance, we might want to add 4 Rust crates:

  • Serde: It’s a framework for serializing and deserializing Rust information constructions effectively and generically. Their crates.io URL is https://crates.io/crates/serde. Serde is used to map JSON information into Rust information constructions or Struct. It’s used to Deserialize or convert JSON to struct and Serialize or convert struct to JSON.
  • Reqwest: It’s HTTP Shopper for Rust. Their crates.io URL is https://crates.io/crates/reqwest. Reqwest is used to make HTTPS requests to Coinbase REST API.
  • Tokio: It’s a platform for writing asynchronous functions. Their crates.io URL is https://crates.io/crates/tokio. Tokio is required to develop an asynchronous software.
  • Clap: It’s a command-line argument parser for Rust. Their crates.io URL is https://crates.io/crates/clap. Clap is required to develop a command-line interface software.

Lastly, Cargo.toml is modified to incorporate 4 crates as follows:

[package]
identify = "rust-struct"
model = "0.1.0"
version = "2021"
# See extra keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html[dependencies]
serde = model = "1.0.136", options = ["derive"]
reqwest = model = "0.11", options = ["json"]
tokio = model = "1.17.0", options = ["full"]
clap = model = "3.1.2", options = ["derive"]

On this article, we are going to use develop a easy software then construct upon an software so as to add further functionalities in subsequent classes:

  • Lesson 1: A Easy Asynchronous Utility that calls Coinbase REST API
  • Lesson 2: Transfer Asynchronous name to REST API to a special perform
  • Lesson 3: Add Command Line Interface
  • Lesson 4: Add Time, Crypto Purchase Worth, Crypto Promote Worth, and Extra CLI Parameters

Lesson 1: A Easy Asynchronous Utility that calls Coinbase REST API

We’ll develop a easy asynchronous software to name Coinbase Worth Knowledge REST API utilizing supplied URL after which course of (i.e., deserialize) the JSON file into programmable objects (i.e., structs) so we will print the crypto costs.

You might ask — why develop an asynchronous software? It is because the next article(s) will improve this software to publish crypto costs to Apache Kafka utilizing rdkafka crate, therefore the identify of the appliance is Crypto Writer.

JSON (response.json)

The next JSON has a hierarchical construction or nested construction as proven beneath:


"information":
"base":"BTC",
"forex":"USD",
"quantity":"40731.94"

Rust Struct

Rust Struct helps nested construction by creating two structs the place the information sort of “CoinPrice” is used to copy JSON’s nested construction. Lastly, it implements Serde’s Deserialize to map JSON information into Rust Struct. The simplest approach to create a struct from JSON file is to goto quicktype (https://app.quicktype.io/) then copy JSON because the supply and specify Rust as a goal. I’ve modified the struct identify to satisfy my wants.

#[derive(Serialize, Deserialize, Debug)]
pub struct CoinbasePrice
pub information: CoinPrice
#[derive(Serialize, Deserialize, Debug)]
pub struct CoinPrice
pub base: String,
pub forex: String,
pub quantity: String,

REST API Request

After we outlined structs, we might want to make REST API request. That is performed following async/.await assemble utilizing Tokio runtime, which is mirrored within the code as:

  • REST API request, which returns a future then await for it to be accomplished (Shopper::new().get(&spot_url).ship().await?)
  • Parse JSON response to ConibasePrice struct, which returns a future then await for it to be accomplished (json::<CoinbasePrice>().await?;)
let resp_spot_price = Shopper::new().get(&spot_url).ship().await?.json::<CoinbasePrice>().await?;

Print out Crypto Worth

Lastly, we print out the crypto worth utilizing struct then return Okay on the finish. Please observe that CoinbasePrice struct is structured as comply with:

CoinbasePrice
information
base
forex
quantity

Since CoinbasePrice struct is assigned to resp_spot_price, base = resp_spot_price.information.base.

println!("SPOT: base-currency: quantity",
base=resp_spot_price.information.base,
forex=resp_spot_price.information.forex,
quantity=resp_spot_price.information.quantity);
Okay(())

Accomplished Code

Lastly, the finished code is supplied beneath the place there are two recordsdata:

  • major.rs: It simply calls crypto_publisher perform in crypto_publisher_1.rs. Please observe the addition of unwrap() since fn crypto_publisher() returns a Outcome sort.
  • crypto_publisher_1.rs

major.rs

crypto_publisher_1.rs

Lesson 2: Transfer Asynchronous name to REST API to a special perform

On this lesson, we are going to accomplish the next:

  • Transfer asynchronous name to REST API to a brand new async perform since we might want to name this perform thrice to get spot worth, purchase worth, and promote worth.
  • Convert crypto_publisher perform to a perform, which calls the brand new async perform.

Create a brand new async perform

A brand new async perform is created so we will use the identical perform to get three costs:

  • Spot Worth
  • Purchase Worth
  • Promote Worth

Therefore, the brand new async perform known as get_coin_price() has three enter parameters:

  • Kind (spot, purchase, and promote)
  • Foreign money (e.g., BTS)
  • Charges (e.g., USD)

and returns a Outcome sort with a String worth, which is represented by Okay(resp_price.information.quantity). All different codes are much like the earlier lesson.

Convert crypto_publisher perform to sync perform

fn crypto_publisher has been simplified to simply name get_coin_price() then print out the parsed returned worth.

Accomplished Code

Lastly, the finished code is supplied beneath the place there are two recordsdata:

  • major.rs: It simply calls crypto_publisher perform in crypto_publisher_2.rs.
  • crypto_publisher_2.rs

major.rs:

crypto_publisher_2.rs:

Lesson 3: Add Command Line Interface

On this lesson, we are going to accomplish the next:

  • Create struct for a Command Line Interface (“CLI”) utilizing Clap, which is an easy to make use of, environment friendly, and full-featured Command Line Argument Parser.
  • Add CLI code perform crypto_publisher()

Create struct for a Command Line Interface

Clap has a Builder API that makes use of attributes on a struct to construct a command-line interface. The next struct provides two parameters:

  • Foreign money (e.g., BTC)
  • Charges (e.g., USD)

Add CLI code perform crypto_publisher()

Now we have added CLI code to async fn crypto_publisher() to just accept command-line interface values.

let args = Cli::parse();
let forex = &args.forex;
let charges = &args.charges;

Accomplished Code

Lastly, the finished code is supplied beneath the place there are two recordsdata:

  • major.rs: It simply calls crypto_publisher perform in crypto_publisher_3.rs.
  • crypto_publisher_3.rs

major.rs:

crypto_publisher_3.rs:

Lesson 4: Add Time, Crypto Purchase Worth, Crypto Promote Worth, and Extra CLI Parameters

Lastly, we full the appliance by bringing all of it collectively. We add the next functionalities:

  • Add a perform to get time
  • Add crypto purchase worth and promote worth in addition to the value unfold between the purchase worth and the promoting worth
  • Add two extra parameters: repeat frequency (or what number of occasions the functions ought to run) and interval (or at what time interval — instance: 30 seconds)

Add a perform to get time

The brand new perform get_coin_time() is similar to get_coin_price() besides it has no enter parameters.

Add crypto purchase worth and promote worth in addition to worth unfold between the purchase worth and the promote worth

We improve crypto_publisher() so as to add further perform requires:

then we carry all collectively to print out costs for Spot Worth, Purchase Worth, Promote Worth in addition to Worth Unfold between Purchase Worth and Promote Worth.

Add two extra parameters: repeat frequency and repeat interval

Utilizing Clap’s Builder API that makes use of attributes on a struct so as to add two extra command-line interface parameters.

  • Interval (e.g., 10)
  • Frequency (e.g., 30000 or 30 seconds)

then we add a loop to include two further CLI parameters.

Accomplished Code

Lastly, the finished code is supplied beneath the place there are two recordsdata:

  • major.rs: It simply calls crypto_publisher perform in crypto_publisher_5.rs.
  • crypto_publisher_5.rs

major.rs

crypto_publisher_5.rs:

I hope this text was useful! Thanks for studying.

More Posts