Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Using Options to pick from multiple potential values
After getting the user's input, we need to figure out a filename to write the file out as. We can either use the title the user passed in, or we can try to use heuristics to find a title from the markdown content. We can combine the user's title from the cli arguments (an `Option`) with the logic we use as a heuristic for the markdown (also an `Option`). ```rust // use `title` if the user passed it in, // otherwise try to find a heading in the markdown let document_title = title.or_else(|| { contents .lines() .find(|v| v.starts_with("# ")) // markdown headings are required to have `# ` with // at least one space .map(|maybe_line| maybe_line.trim_start_matches("# ").to_string()) }); ``` `option.or_else()` returns the original option if it is a `Some` value, or executes the function to return a different `Option` if not. So `document_title` is an `Option<String>` either way and we've covered all of the possible scenarios: 1. the user has passed in a title 2. the user has written content with a heading 3. the user has done neither of these Which leaves us to our markdown heuristic. Markdown headings are required to have `# ` with at least one space, so we can turn `contents` into an iterator and `find` the first line that starts with `# `. If we find one, we want to trim `# ` off of the heading to get just the heading content, so we can use `map` to operate on the value inside of the `Option` returned by `find` if it exists. ```rust contents .lines() .find(|v| v.starts_with("# ")) .map(|maybe_line| maybe_line.trim_start_matches("# ").to_string()) ``` Now this code works fine, but it exposes a bug in our file handling. If we `write_all` to the `file`, that moves the internal cursor to the end of that content. So when we run our code now, `contents` is skipping the first `# ` bytes, which means our heuristic will only find the second heading in the file. To fix this, we can bring in the `std::io::Seek` trait, and seek to the beginning of the file. ```rust let mut contents = String::new(); file.seek(SeekFrom::Start(0))?; file.read_to_string(&mut contents)?; ```
- Loading branch information