Embedding simple CSV file and processing in a functional way

include_str! lines filter is_empty map

In an earlier article I described how to embed a simple CSV file in the code.

I got some suggestions to improve the code from Marcus Bosten. So let's see those.

To remind you the idea was to embed a simple CSV file in the code and then read it into a HashMap.

This is how the CSV file looks like:

examples/embedded-simple-csv-file-functional/data/languages.csv

rs,rust
sh,bash

toml,toml
lock,toml

This is the new code based on the suggestions from Marcus.

A few notes

  • lines method allows us to iterate over the lines of a string.
  • filter method allow use to, well, filter out some of the entries. In this case we wanted to process only the lines that are not empty.
  • map method processes each entry and for each entry returns something. In this case returns a tuple.
  • split_once is also used to makes sure if there are multiple commas in the string we only split on the first one.
  • This code will panic if there is a non-empty line that has no comma in it. We could also use the filter to filter out and disregard those lines.

examples/embedded-simple-csv-file-functional/src/main.rs

use std::collections::HashMap;

fn main() {
    let ext_to_languages = get_languages();

    println!("{:?}", ext_to_languages);
    println!("{:?}", ext_to_languages["rs"]);

    assert_eq!(ext_to_languages["rs"], "rust");
}

fn get_languages() -> HashMap<String, String> {
    let text = include_str!("../data/languages.csv");

    text.lines()
        .filter(|line| !line.is_empty())
        .map(|line| {
            let (key, value) = line.split_once(',').expect("no comma? no results");
            (key.to_owned(), value.to_owned())
        }).collect::<HashMap<String, String>>()
}