Cool trick using Rust awesome type system

67 points omagdy7

Hello guys I am solving advent of code this year in rust and started using a trick that I think worth sharing since it's not very well known(at least for non-experienced rust programmers).

The problem:

in advent of code there are two parts for the same problem and the input for the two parts is identical, but sometimes which is the case for today's challenge the parsing for part 2 was slightly different than part 1. usually I solve these challenges by trying to encapsulate the puzzle input in some sort of struct and implementing From<&str> for that struct from the puzzle input and then start processing that struct that usually works pretty well, but sometimes causes a slight inconvenience that when part 2 parsing changes slightly. I end up making pretty much identical struct and applying From<&str> for that with the modification required.

Solution:

I lately stumbled upon PhantomData<T> and type state pattern which allowed for a rather more ergonomic API if I do say so myself essentially now I do this:

struct One;
struct Two;

struct SomeStruct<Part = One> {
    some_state: Vec<String>,
    part: std::marker::PhantomData<Part>,
}

impl From<&str> for SomeStruct<One> {
    fn from(value: &str) -> Self {
        todo!()
    }
}
impl From<&str> for SomeStruct<Two> {
    fn from(value: &str) -> Self {
        todo!()
    }
}

fn main() {
    let my_struct_1: SomeStruct<One> = SomeStruct::from("today's input");
    let my_struct_2: SomeStruct<Two> = SomeStruct::from("today's input");
}

Which I think looks pretty clean and the best part it has zero runtime costs as well!