Damon Marc Rocha II
Posted on June 24, 2020
Hello, how are you all today? I want to introduce any and all programmers out there to Rust. A newer programming language similar to C++ but with more security. Due to the fact that C++ was my first programming language, I feel a certain nostalgia for it and enjoy the fact that it has an awesome package manager, cargo. So what I am going to do here is show you Rust newbies how to get started and then go over a project I just build a Morse code en/decoder.
I was introduced to Rust by my teacher at Flatiron upon asking him how I would go about building my own OS from scratch. Now before you ask no I am not at this point yet, but I do believe that I will be there soon. After trying it out I realized I really liked it, I really did. So fast forward to now and I am done with my first major project using Rust with many more soon to come.
But enough of that lets set up Rust. First download rust to Linux or a Linux sub-system with the command:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
This command downloads rust and cargo to your system if you are using something else well then go to the Rust start page: https://www.rust-lang.org/learn/get-started
and follow the prompts.
Now check if you got cargo
cargo --version
Then if the latest cargo version shows up you are ready to build programs with rust easy right?
Cargo gives you some pretty awesome commands such as:
cargo build //compiles your Rust programs
cargo run //compiles and runs your Rust programs
cargo test //tests your Rust programs
cargo doc // creates docs for your program
cargo publish //publishes your program to crate.io
cargo new project-name //generates a new project
This here is just the beginning of rust to learn more go to their free books and docs here: https://www.rust-lang.org/learn
Now On to My Project. I built a morse code encode/decoder CLI project that allows a user to input text or morse code and then the get the translation. To do this I created a MorseDecoder Struct and then used two functions in its impl block to convert the users input
struct MorseDecoder {
morse_code: HashMap<String, String>
}
impl MorseDecoder {
fn convert_to_morse(&self, message: &str) -> String{
let mut refined: Vec<String> = vec![];
for c in message.chars(){
refined.push(c.to_string());
}
let mut decoded_string: Vec<String> = vec![];
for code in refined{
if code == " "{
decoded_string.push(" ".to_string());
}
else{
for (k, v) in self.morse_code.iter(){
if v.to_string() == code{
decoded_string.push(k.to_string());
decoded_string.push(" ".to_string());
break;
}
}
}
}
return decoded_string.join("").trim().to_string()
}
fn decode_morse(&self, encoded: &str) -> String {
let refined: Vec<String> = encoded
.split(" ")
.map(|s| s.parse().expect("parse error"))
.collect();
let mut decoded_string: Vec<String> = vec![];
let mut space_count = 0;
for code in refined{
if code == ""{
if space_count < 1{
space_count += 1;
decoded_string.push(" ".to_string());
}
else{
space_count = 0;
}
}
else{
for (k, v) in self.morse_code.iter(){
if k.to_string() == code{
decoded_string.push(v.to_string());
break;
}
}
}
}
return decoded_string.join("").trim().to_string()
}
}
I ran into a few problems with the spacing translation but solved this by counting the number of consecutive spaces in the vector. Then Since two spaces are considered a space in morse I would push a space character to the vector when this condition was met. Converting to morse code was much easier and really all I did was split up the message into a vector then match it with the corresponding value in the struct's hash.
The last issue I came across was when trying to compare strings on user input.
fn code_translator(message: String) -> String{
...
if choice.to_uppercase() == String::from("ENCODE"){
let mut message = String::new();
println!("Enter Message:");
io::stdin()
.read_line(&mut message)
.expect("Failed to read line");
return decoder.convert_to_morse(&message.trim())
}
else if choice.to_uppercase() == String::from("DECODE"){
let mut message = String::new();
println!("Enter Message");
io::stdin()
.read_line(&mut message)
.expect("Failed to read line");
return decoder.decode_morse(&message.trim())
}
else{
return String::from("Invalid Entry")
}
}
fn main(){
...
let mut code_choice = String::new();
io::stdin()
.read_line(&mut code_choice)
.expect("Failed to read line");
let code_choice = code_choice.trim().to_string();
println!("New Message: {}",code_translator(code_choice));
...
}
In io::stdin() block the input users enter is saved to code_choice but the catch is it also saves a new line character. Which caused some problems when trying to compare in the code_translator function. To solve this issue I used the .trim() function to get rid of the new line character.
With all of this done I was finished with this project.
This was a challenging project, but really shows how much I have learned in Rust. I cannot wait for the next one
To see the entire repo go to:https://github.com/dmarcr1997/rust_morse_code_decoder_cli
Posted on June 24, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.