DEV Community

AmasiaNalbandian
AmasiaNalbandian

Posted on

A lil' rusty

The assignment:

This week I when I learned we had to create another PR for our CLI's I decided the best thing to do was get back in touch with Jerry!

A few weeks back, I saw a post he made about not having any PR's for his repository - and I was more than happy to put one in for him, however there was one problem... Jerry's approach used Rust - I have never even seen Rust syntax in my life!

First Impression:

So for the month of October, as Halloween approaches I decided to do something scary... I picked his repository and we are going to learn Rust!

When I started reading the code, I realized that Rust looked like a grocery store receipt... none of the syntax looked to be a full word. I was shocked at how much I was able to pick up though. I was able to read the implementation very easily with keywords such as fn, or enums - all familiar.

The approach:

The funniest thing about this week's contribution was that I was able to understand the code, and knew what I needed to do - but I had no idea how to write it.

The first thing I asked Jerry to help me learn Rust was how to print out variables. The syntax is very similar to C++: println!("{:?}", variable_you_want_to_print)

Next, I Googled how to parse JSON files in Rust. Surprisingly, there was a "crate" that would completely take care of this using key and value pairs. This post included a third response which clearly explained how I would use this crate to parse JSON files.

I quickly realized how similar Rust syntax was to C/C++, and was able to understand how to read the config file. Additionally, I was able to then read, and parse the JSON file. Next, came the biggest hurdle in the project - the parsing was not giving me the result I wanted. I used my println to see what the variable was being stored as: mintty_wal7wKvNkG

Debugging

Issue #1
As you can see, it kept storing the string with escapes for the quotation marks. After two hours, I decided to ask Jerry for some help. I provided him with my approach and he forwarded the documents for serde_json. I had already read these, but discussed the options anyways. I was then able to understand my approach was wrong. I was using the json.get("input") which he explained would give me a reference, but not the actual value. We then discussed how serde_json is actually storing a hashmap when declaring the json variable as serde_json::Value. Next, I was able to understand that we can use json["input"] to get the reference to where the value is stored, and Jerry added to then use as_str() to grab the actual value and store it. Additionally, he suggested we attach .to_owned() to ensure we are not storing a copy.

Issue #2
After this I was able to successfully get the input property to work! However, I was running into problems with the "language" flag... At first I thought it was overwriting the options, or only putting in input. The JSON config file I was using only had language and input properties. I decided to add the output too, to see if it would make a difference. That's weird... Output works... This is where I realized I am making silly mistakes. The JSON file specified a property "lang" not "language". Ofcourse there was no index for "language". Oops - user error.

Not so rusty anymore...

When I first began this project, I thought i'm going to learn a new language! So here's what I learned from Rust:

  1. Enums can take additional values: image
  2. How to declare functions: fn parse_config(config: &String) -> Vec<Option> {} Here you can see fn means function - we are declaring a function. parse_config is the name of the function, and it accepts a value called config which is a string. The '->' indicates the return, a vector of type Option(as seen above in the image for enum Option).
  3. Return values: When you want to return something, you simply write the variable in the last line of the function block. Make sure you do not include a semi-colon (been there, done that!).
  4. There's no try catch... There's expected. When you run a line of code and you "expect" it to pass, it will not use a try/catch, instead it will use expected, and anything in the bracket will return the catch. let file = fs::File::open(config).expect("file should open read only");

let json: serde_json::Value = serde_json::de::from_reader(file).expect("unable to read to json");

So I expect that the file will be read, otherwise it will print
"file should open read only"
I expect the file to read from serde_json, otherwise print" unable to read to json".

Results: My braincells

I learned enough Rust to add a feature!!

Top comments (0)