Jean-Marcel Belmont
Software Engineer with passion for automation
A command-line interface or command language interpreter (CLI), also known as command-line user interface, console user interface and character user interface (CUI), is a means of interacting with a computer program where the user (or client) issues commands to the program in the form of successive lines of text (command lines). A program which handles the interface is called a command language interpreter or shell (computing).
According to wikipedia:
Rust has several different ways to iterate through collections!
Let us write a Rust Script that makes an HTTP Request
Here we use the reqwest library to make an HTTP request
We will break apart the 2 summation functions from the main.rs into the lib.rs
Notice here that we add pub for public visibility
Notice here that we now use our lib as an internal crate!
We call our public method with the crate name now.
We add the following annotation to create our unit test cases.
Now we can unit test our cli program by issuing the cargo test command
Notice here that both of our unit test cases run when we run cargo test!
Using Clap to build Robust Clis in Rust
Clap has many features to build robust features
Using Clap to build Robust Clis in Rust
let matches = App::new("Calculator")
.subcommand(SubCommand::with_name("add")
.about("Sum some numbers")
.version("0.1")
.author("Jean-Marcel Belmont")
.arg(Arg::with_name("numbers")
.multiple(true)
.help("the numbers to add")
.required(true)))
.subcommand(SubCommand::with_name("subtract")
.about("Subtract some numbers")
.version("0.1")
.author("Jean-Marcel Belmont")
.arg(Arg::with_name("numbers")
.multiple(true)
.help("the numbers to subtract")
.index(1)
.required(true)))
Here we use subcommands to build a calculator cli application
Here we run the binary executable to run our simple calculator cli application
Notice that each subcommand performs a different calculation.
Also notice that we are using the binary executable here.
It is created upon successful `cargo run` and/or `cargo build`.
We will write a command line application in Rust.
It will base64 decode a json web token to standard output
Use statements
Library Dependencies
Here are 3 Structs and notice that the Token struct has both the Header and Claims struct embedded in it.
The new methods for the Claims and Headers structs instantiate a new Claims and Header instance.
Having some ascii fun now in the command line
Having some ascii fun now in the command line
This C program generates ascii characters to standard output.
This shell command replaces the output with single quotes and adds a comma to the end except last line.
Let us take out the portion of the main ascii_table.c that print out to ascii and put it into its own c source file
Let us use the clang compiler to generate an object file and then help the rust compiler find the symbol to use in C.
We can find the generated symbol in the print_ascii.o object file using objdump utility.
Notice here that the printAscii exists in the object file and so we can use this symbol using a concept called foreign function interface
We can use the unsafe keyword that is talked about in the Rust Book Chapter 19 to call our printAscii function written in C
Notice that here we wrap the printAscii function with the extern keyword
We then call it using an unsafe block in Rust
Remember that we then compiled our rust main file and used a couple of options helping the rust compiler locate the symbol that we will use in C.
Here notice that the rust compiler has several options that we need to use
rustc src/main.rs -l print_ascii.o -L .
This will generate a binary executable called main that we can run now.
Here are our dependencies for the Web Scraping project:
Here is our use and crate statements:
Here is the main logic for the Web Scraping Project
Here is the main function:
Notice that we ran the run() function and wrap it in a `if let` statement which will print error and exit if there is an error.
Printing with named value
Pretty Print with println("{:#?}", something);
Debugging Rust applications with rust-lldb.
There are 2 debuggers that come prebundled with cargo:
If you are working on Mac OS X it is easier to use rust-lldb
You can use gdb in Mac OS X but it requires extra steps:
First install gdb, easiest way is via homebrew package manager
Next you will need to codesign gdb, if you are interested follow the steps in this CODESIGN-GIST
For the purposes of this demo we will use rust-lldb
Here we start rust-lldb using the compiled binary executable
Notice here that we run the main.rs file by issuing the command run
Let us set a breakpoint in lldb
This is the short form version of setting a breakpoint
This is the longer but more powerful way to set breakpoint
Let us run our program with breakpoint set
Notice here that lldb stopped in line 6 which is our breakpoint!
We issued command "frame variable args" to see variable
Note that the commands for printing: p (simple types), po (objects), and pa (arrays) don't work as well with Rust.
The frame command is used to examine current stack frame and has various subcommands such as variable which work better!
Step over with lldb
Resume/Continue execution of program
Notice here that we continued until the next breakpoint!
List breakpoints
Delete all breakpoints
Delete specific breakpoint(s)
First do Instruction level single step, stepping over calls
Next actually step into function
Next let us step over and then print value of variable
Step out of the function
Get stack frame information and continue execution
Use expression to set values in running program
Print back trace information
Kill lldb session
Useful Rust Libraries for Command Line Applications:
Parse command line argument by defining a struct. It combines clap with custom derive.
It is a simple-to-use, efficient, and full-featured library for parsing command line arguments and subcommands when writing console/terminal applications.
Useful Rust Libraries for Command Line Applications:
A Rust library providing a lightweight logging facade. A logging facade provides a single logging API that abstracts over the actual logging implementation. Libraries can use the logging API provided by this crate, and the consumer of those libraries can choose the logging implementation that is most suitable for its use case.
A rust library for indicating progress in command line applications to users.
Useful Rust Libraries for Command Line Applications:
A tool to help invoke fuzzers in Rustlang
Easy command initialization and assertions.
Proptest is a property testing framework inspired by the Hypothesis framework for Python. It allows to test that certain properties of your code hold for arbitrary inputs, and if a failure is found, automatically finds the minimal test case to reproduce the problem.
Useful Rust Libraries for Command Line Applications:
Library for safe and correct Unix signal handling in Rust.
The asynchronous run-time for the Rust programming language.
Please read the most excellent Rustlang Nursery online book on writing command line applications in Rust: https://rust-lang-nursery.github.io/cli-wg/index.html
Checkout my new book titled Hands On Continuous Integration with Jenkins, Travis, and Circle CI
By Jean-Marcel Belmont
A talk focusing on building command line applications with Rust and Golang.