Rust Fundamentals with A morse code decoder
Tags: rust, ubuntu, cargo, cli
Published: 2020-06-24 17:31:44

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

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/zbmk2zfjd6ufrmozkvrk.gif)

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