remi-dupre/aoc

Allow for `Result` or `Option` outputs

Closed this issue · 7 comments

From a reddit suggestion.

I am not sure how this would be implemented, maybe it would require a proper syntax to indicate that the output needs to be unwrapped, maybe we would reach the limit of using a macro_rule.

macro_rules! test {
    (
        year $year: expr;
        $( $day: ident $( : $generator: ident )? => $( $solution: ident $( ? )? ),+ );+
        $( ; )?
    ) => {};
}

test! {
    year 2020;
    day1 : generator => part1?, part2;
}

This appears to work fine, I suppose suffixing with ? could be a nice syntax :)

For solvers, have you considered using Debug instead of Display?

For solvers, have you considered using Debug instead of Display?

Display seems to be a nice way to go in order to get an inline message for the error:

Screenshot_2020-12-09_20-40-15

Implemented by #8

Setting up aoc-main for last years aoc and trying to run/compile I get this:

   Compiling aoc-2019 v0.1.0 (C:\Dev\WebStorm\Advent of Code\2019)
error[E0277]: `std::option::Option<i32>` doesn't implement `std::fmt::Display`
  --> src\main.rs:6:1
   |
6  | / aoc_main::main! {
7  | |     year 2019;
8  | |     day01 : input_generator => solve_part1, solve_part2;
9  | |     day02 : input_generator => solve_part1, solve_part2;
10 | |     day03 : input_generator => solve_part1, solve_part2;
11 | |     day04 : input_generator => solve_part1, solve_part2;
12 | | }
   | |_^ `std::option::Option<i32>` cannot be formatted with the default formatter
   |
   = help: the trait `std::fmt::Display` is not implemented for `std::option::Option<i32>`
   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
   = note: required by `std::fmt::Display::fmt`
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

my cargo.toml is like this:

[dependencies]
aoc-main = { git = "https://github.com/remi-dupre/aoc.git", branch = "main" }

It is a fresh install so it aught to be getting the latest changes, including #8

Hi @Silver-Golden!

You'd probably want to tell aoc-main to unwrap the value by suffixing your solutions returning and Option with ? (cf the example). I should probably add a line or two about that in the README ^^

It also makes me wonder how I could allow for something more general than Display as results but still keep a pretty output 🤔

EDIT: I now understand that this last one was the exact suggestion from @WhoisDavid, however I think Debug may be quite ugly in some cases (such as String which would be quoted), maybe the easiest way to go would be to have a special trait which would decide whether Display or Debug would be preferred.

I agree that it would be nice to at least have the option to format using Debug instead of Display. Using Display makes it impossible to return tuples for example, which I found necessary for this year's day 9, meaning I needed to manually create a new struct and implement display for it to get everything working:

pub struct Answer(u64, u64);

use std::fmt;
impl fmt::Display for Answer {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Part 1: {}, Part 2: {}", self.0, self.1)
    }
}

pub fn solve_both_parts(input: &[u64]) -> Answer {
    let part1_result = solve_part1_with_preamble_length(input, 25);
    let part2_result = solve_part2_from_part1(input, part1_result);
    Answer(part1_result, part2_result)
}

vs. just:

pub fn solve_both_parts(input: &[u64]) -> (u64, u64) {
    let part1_result = solve_part1_with_preamble_length(input, 25);
    let part2_result = solve_part2_from_part1(input, part1_result);
    (part1_result, part2_result)
}