Handling newline characters in Rust - counting unique occurrences : I'm creating a compression/decompression library in Rust using Huffman encoding. One of the first steps is creating a data structure that contains all unique characters and the number of occurrences. I'm starting with just a simple text file, and having issues related to newline 'characters'.

My first attempt at solving this problem was constructing a `BTreeMap`, essentially a key-value pair of unique characters and their occurrences, respectively. Unfortunately, a newline 'character' is \n, which I think is not being handled corrected due to being two characters. I then converted the `BTreeMap` into a `Vec` to order by value, but that didn't solve the newline issue.

Here's my initial attempt at my `comp` binary package. Calling the binary is done using `cargo`, and my sample file is reproduced at the end of this question:

    cargo run <text-file-in> <compressed-output-file>

`main.rs`:

    extern crate comp;
    
    use std::env;
    use std::process;
    use std::io::prelude::*;
    
    use comp::Config;
    
    fn main() {
        // Collect command-line args into a vector of strings
        let mut stderr = std::io::stderr();
    
        let config = Config::new(env::args()).unwrap_or_else(|err| {
            writeln!(&mut stderr, "Parsing error: {}", err).expect("Could not write to stderr");
            process::exit(1)
        });
    
        println!("Filename In: {}", config.filename_in);
        println!("Filename Out: {}", config.filename_out);
    
        if let Err(e) = comp::run(config) {
            writeln!(&mut stderr, "Application error: {}", e).expect("Could not write to stderr");
            process::exit(1);
        }
    }

`lib.rs`:

    use std::collections::btree_map::BTreeMap;
    use std::error::Error;
    use std::fs::File;
    use std::io::Read;
    use std::iter::FromIterator;
    
    pub struct Config {
        pub filename_in: String,
        pub filename_out: String
    }
    
    impl Config {
        pub fn new(mut args: std::env::Args) -> Result<Config, &'static str> {
            args.next();
    
            let filename_in = match args.next() {
                Some(arg) => arg,
                None => return Err("Didn't get a filename_in string"),
            };
    
            let filename_out = match args.next() {
                Some(arg) => arg,
                None => return Err("Didn't get a filename_out string"),
            };
    
            Ok(Config {
                filename_in: filename_in,
                filename_out: filename_out,
            })
        }
    }
    
    pub fn run(config: Config) -> Result<(), Box<Error>> {
        let mut f = File::open(config.filename_in)?;
    
        let mut contents = String::new();
        f.read_to_string(&mut contents)?;
    
        for line in contents.lines() {
            println!("{}", line);
        }
    
        // Put unique occurrences into a BTreeMap
        let mut count = BTreeMap::new();
    
        for c in contents.chars() {
            *count.entry(c).or_insert(0) += 1;
        }
    
        // Put contents into a Vec to order by value
        let mut v = Vec::from_iter(count);
        v.sort_by(|&(_, a), &(_, b)| b.cmp(&a));
    
        // Print key-value pair of input file
        println!("Number of occurrences of each character");
        for &(key, value) in v.iter() {
            println!("{}: {}", key, value);
        }
    
        Ok(())
    }

Any criticism is welcome.

---

Sample text file, `poem.txt`:

    I'm nobody! Who are you?
    Are you nobody, too?
    Then there's a pair of us — don't tell!
    They'd banish us, you know.
    
    How dreary to be somebody!
    How public, like a frog
    To tell your name the livelong day
    To an admiring bog!

