This crate contains some helper methods that I regularly use in my Advent of Code solutions.
args::get_args
Reads the command line arguments and checks whether the correct number of arguments are present.
```rust use rdclaochelpers::args::get_args;
fn main() {
let args = get_args(&["", "
error::WithOrExit
This trait adds a or_exit_with
method.
The purpose of this method, is to allow you to easily let your program terminate with a specific exit code.
It has been implemented for [Result] and [Option].
The implementation for [Result] requires that the associated error type implements [fmt::Debug].
```rust use rdclaochelpers::error::WithOrExit;
fn main() { someoperationthatreturnsaresult() .orexit_with(25); } ```
error::ParseError
A generic error containing just a message. It implements [fmt::Display] and [fmt::Debug], and it can be converted from [io::Error] and [num::ParseIntError].
```rust use rdclaochelpers::error::ParseError;
fn examplewithparams(param: u8) -> Result<(), ParseError> { if process(param) { Ok(()) } else { Err(ParseError(format!("Failed to process param: {}", param))) } }
fn examplewithoutparams() -> Result<(), ParseError> { if process() { Ok(()) } else { Err(ParseError.of("Failed to process")) } } ```
input::MultilineFromStr
This trait is inspired by the [str::FromStr] trait, and allows you to parse input where data might span several lines.
```rust use rdclaochelpers::error::ParseError; use rdclaochelpers::input::MultilineFromStr;
pub struct Record {
items: Vec
impl MultilineFromStr for Record { type Err = ParseError;
fn new() -> Self {
Record {
items: Vec::new(),
}
}
fn indicates_new_record(&self, line: &str) -> bool {
line.is_empty()
}
fn parse(&mut self, line: &str) -> Result<(), Self::Err> {
if !line.is_empty() {
self.items.push(line.parse::<u8>()?);
}
Ok(())
}
} ```
input::WithReadLines
This trait adds a read_lines
method.
The purpose of this method is to read the lines from some source (e.g. a file), and then convert each line to a specific type.
As an argument, this method takes an exit code that should be used if processing the source fails, and it returns an iterator.
This trait has been implemented for [fs::File].
```rust use rdclaochelpers::input::WithReadLines;
fn main() {
for item in File::open("./my-file.txt").read_lines::
input::WithReadMultiLines
This trait adds a read_multi_lines
method.
It's the equivalent of input::WithReadLines
, but rather than depending on [str::FromStr], it depends on input::MultilineFromStr
.
```rust use rdclaochelpers::input::WithReadMultiLines;
fn main() {
for record in File::open("./my-file.txt").readmultilines::
struct Record { /* ... / } impl MultilineFromStr for Record { / ... */ } ```
input::WithAsRecords
& input::WithAsMultilineRecords
These traits allow you to easily convert an object to a vec of items of the required type.
```rust
mod tests { use rdclaochelpers::input::WithAsRecords; use rdclaochelpers::input::WithAsMultilineRecords;
use super::*;
#[test]
fn test_simple() {
let input = vec!["1", "2", "3", "4", "5"]
.as_records::<u8>()
.unwrap();
assert_eq!(input, vec![1, 2, 3, 4, 5]);
}
#[test]
fn test_multiline() {
let input = vec!["1", "2", "", "3", "4", "", "5"]
.as_multiline_records::<Record>()
.unwrap();
assert_eq!(
input,
vec![
Record { items: vec![1, 2] },
Record { items: vec![3, 4] },
Record { items: vec![5] },
]
);
}
} ```
part::Part
This enum is useful if you need to explicitly refer to a part. It implemts [str::FromStr] and [fmt::Display], so you can easily convert to and from a string.
```rust use rdclaochelpers::part::Part;
fn main() {
let part = "part 1".parse::
let part = Part::Two;
println!("[{}] ...", part); // outputs "[part 2] ..."
} ```