statiolake / proconio-rs

Apache License 2.0
126 stars 7 forks source link

Add run-time version of Readable #50

Closed statiolake closed 7 months ago

statiolake commented 7 months ago

Currently, you cannot define the readable which uses the prior inputs or run-time values to determine how to parse the input. That means you can't define user-defined version of built-in [T] or [T; n], which uses the prior input as its length.

This feature, RuntimeReadable, allows you to define such a readable. For example, you can define a readable for your directed graph:

struct DirectedGraphReadable(usize, usize);

impl RuntimeReadable for DirectedGraphReadable {
    type Output = Vec<Vec<usize>>;

    fn read<R: BufRead, S: Source<R>>(self, source: &mut S) -> Self::Output {
        let DirectedGraphReadable(n, m) = self;

        input! {
            from source,
            edges: [(Usize1, Usize1); m],
        };

        let mut g = vec![vec![]; n];
        for e in edges {
            g[e.0].push(e.1);
        }
        g
    }
}

let mut source = AutoSource::from("2 3\n1 1\n1 2\n2 2\n");
input! {
  from source,
    n: usize,
    m: usize,
    g: with DirectedGraphReadable(n, m),
}

As you can see in the above snippet, you need to specify the runtime readable after with for the RuntimeReadable.

Closes #48