aoc-helpers 0.2.0

Helpers for the Advent of Code
Documentation
# AOC lib

Rust helper for the [Advent of code](https://adventofcode.com/), should save you some time of copying and pasting the inputs and ansers.

## Usage

To start, you must first pass your advent of code session to the library.

1.  Open [adventofcode.com]https://adventofcode.com/
2.  Open the DevTools (Ctrl+Shift+I might change depending on your platform)
    - For Firefox: DevTools > Storage > Cookies > Copy the session cookie
    - For Chrome: DevTools > Application > Cookies > Copy the session cookie
3.  Set the `AOC_SESSION` environment variable to the copeid session or use `AocSession::new_from_session` with the session.

To avoid submitting the same answer multiple times, an `aoc-progress.json` file is stored in the current directory tracking your progress.

## Example

This example of the first and second part of day 2 (aoc 2021) should pretty much explain how the library works.

```rust
use aoc_lib::{AocSession, Day};
use std::{convert::Infallible, str::FromStr};

enum SubmarineCommand {
    Forward(i32),
    Up(i32),
    Down(i32),
}

struct Day2(Vec<SubmarineCommand>);

impl Day for Day2 {
    fn from_input(input: String) -> Self {
        let lines = input.trim().split('\n');
        let mut commands = vec![];

        for line in lines {
            commands.push(line.parse().unwrap());
        }

        Self(commands)
    }

    fn first_part(&mut self) -> String {
        let mut depth: i32 = 0;
        let mut x: i32 = 0;

        for command in &self.0 {
            match command {
                SubmarineCommand::Down(c) => depth += c,
                SubmarineCommand::Up(c) => depth -= c,
                SubmarineCommand::Forward(c) => x += c,
            }
        }

        (depth * x).to_string()
    }

    fn second_part(&mut self) -> String {
        let mut depth = 0i32;
        let mut aim = 0i32;
        let mut x = 0i32;

        for command in &self.0 {
            match command {
                SubmarineCommand::Forward(c) => {
                    x += c;
                    depth += aim * c;
                }
                SubmarineCommand::Down(c) => aim += c,
                SubmarineCommand::Up(c) => aim -= c,
            }
        }

        (depth * x).to_string()
    }
}

impl FromStr for SubmarineCommand {
    type Err = Infallible; // Just panic!

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let raw_command = s.split(' ').collect::<Vec<_>>();

        Ok(match (raw_command[0], raw_command[1]) {
            ("forward", count) => Self::Forward(count.parse().unwrap()),
            ("down", count) => Self::Down(count.parse().unwrap()),
            ("up", count) => Self::Up(count.parse().unwrap()),
            _ => unreachable!(),
        })
    }
}

fn main() -> Result<(), anyhow::Error> {
    /// More the one .day can be set
    AocSession::new(2021)?.day::<Day2>(3)?;
    Ok(())
}
```