Benchmark reporting;

Build red coloring for actual output if different from expected
Removed dependency colon ... with prettytable
This commit is contained in:
BoolPurist 2024-08-30 15:17:22 +02:00
parent a3ce12a80b
commit 603ee1827d
8 changed files with 310 additions and 94 deletions

207
Cargo.lock generated
View file

@ -8,10 +8,10 @@ version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
"colonnade",
"derive_more", "derive_more",
"env_logger", "env_logger",
"log", "log",
"prettytable-rs",
"ron", "ron",
"serde", "serde",
"solutions_advent_of_code_2023", "solutions_advent_of_code_2023",
@ -97,6 +97,12 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.16" version = "4.5.16"
@ -137,16 +143,6 @@ version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
[[package]]
name = "colonnade"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "833230a1f610c0f3418a80b03c387be9de15b1172b3785b702961ead07e3e475"
dependencies = [
"strip-ansi-escapes",
"unicode-segmentation",
]
[[package]] [[package]]
name = "colorchoice" name = "colorchoice"
version = "1.0.2" version = "1.0.2"
@ -159,7 +155,7 @@ version = "0.15.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb"
dependencies = [ dependencies = [
"encode_unicode", "encode_unicode 0.3.6",
"lazy_static", "lazy_static",
"libc", "libc",
"windows-sys", "windows-sys",
@ -174,6 +170,27 @@ dependencies = [
"unicode-segmentation", "unicode-segmentation",
] ]
[[package]]
name = "csv"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe"
dependencies = [
"csv-core",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "csv-core"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "derive_more" name = "derive_more"
version = "1.0.0" version = "1.0.0"
@ -196,12 +213,39 @@ dependencies = [
"unicode-xid", "unicode-xid",
] ]
[[package]]
name = "dirs-next"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
dependencies = [
"cfg-if",
"dirs-sys-next",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]] [[package]]
name = "encode_unicode" name = "encode_unicode"
version = "0.3.6" version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "encode_unicode"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
[[package]] [[package]]
name = "env_filter" name = "env_filter"
version = "0.1.2" version = "0.1.2"
@ -225,12 +269,29 @@ dependencies = [
"log", "log",
] ]
[[package]]
name = "getrandom"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.5.0" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
[[package]] [[package]]
name = "humantime" name = "humantime"
version = "2.1.0" version = "2.1.0"
@ -249,12 +310,29 @@ dependencies = [
"similar", "similar",
] ]
[[package]]
name = "is-terminal"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b"
dependencies = [
"hermit-abi",
"libc",
"windows-sys",
]
[[package]] [[package]]
name = "is_terminal_polyfill" name = "is_terminal_polyfill"
version = "1.70.1" version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itoa"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.5.0" version = "1.5.0"
@ -267,6 +345,16 @@ version = "0.2.158"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
[[package]]
name = "libredox"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags",
"libc",
]
[[package]] [[package]]
name = "linked-hash-map" name = "linked-hash-map"
version = "0.5.6" version = "0.5.6"
@ -285,6 +373,20 @@ version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "prettytable-rs"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eea25e07510aa6ab6547308ebe3c036016d162b8da920dbb079e3ba8acf3d95a"
dependencies = [
"csv",
"encode_unicode 1.0.0",
"is-terminal",
"lazy_static",
"term",
"unicode-width",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.86" version = "1.0.86"
@ -303,6 +405,17 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "redox_users"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
dependencies = [
"getrandom",
"libredox",
"thiserror",
]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.10.6" version = "1.10.6"
@ -344,6 +457,18 @@ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]]
name = "rustversion"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
[[package]]
name = "ryu"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.209" version = "1.0.209"
@ -380,15 +505,6 @@ dependencies = [
"thiserror", "thiserror",
] ]
[[package]]
name = "strip-ansi-escapes"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55ff8ef943b384c414f54aefa961dd2bd853add74ec75e7ac74cf91dba62bcfa"
dependencies = [
"vte",
]
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.11.1" version = "0.11.1"
@ -406,6 +522,17 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "term"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
dependencies = [
"dirs-next",
"rustversion",
"winapi",
]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.63" version = "1.0.63"
@ -438,6 +565,12 @@ version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
[[package]]
name = "unicode-width"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.2.5" version = "0.2.5"
@ -451,24 +584,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]] [[package]]
name = "vte" name = "wasi"
version = "0.11.1" version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5022b5fbf9407086c180e9557be968742d839e68346af7792b8592489732197" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [ dependencies = [
"utf8parse", "winapi-i686-pc-windows-gnu",
"vte_generate_state_changes", "winapi-x86_64-pc-windows-gnu",
] ]
[[package]] [[package]]
name = "vte_generate_state_changes" name = "winapi-i686-pc-windows-gnu"
version = "0.1.2" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e369bee1b05d510a7b4ed645f5faa90619e05437111783ea5848f28d97d3c2e" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
dependencies = [
"proc-macro2", [[package]]
"quote", name = "winapi-x86_64-pc-windows-gnu"
] version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"

View file

@ -15,4 +15,4 @@ env_logger = "0.11.5"
log = "0.4.22" log = "0.4.22"
anyhow = "1.0.86" anyhow = "1.0.86"
ron = "0.8.1" ron = "0.8.1"
colonnade = "1.3.3" prettytable-rs = "0.10.0"

View file

@ -1,8 +1,7 @@
pub use conducted_benchmark::ConductedBenchmark; pub use conducted_benchmark::ConductedBenchmark;
pub use file_to_benchmark::FileToBenchmark; pub use file_to_benchmark::FileToBenchmark;
use row_builder::COLUMN_NUMBER; use prettytable::Table;
use row_building::MatrixReport;
mod conducted_benchmark; mod conducted_benchmark;
mod file_to_benchmark; mod file_to_benchmark;
@ -15,12 +14,11 @@ use crate::{
AppError, AppResult, AppError, AppResult,
}; };
use anyhow::anyhow; use anyhow::anyhow;
use colonnade::Colonnade;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
pub type BenchmarkResult = Result<ConductedBenchmark, NoSolutionFound>; pub type BenchmarkResult = Result<ConductedBenchmark, NoSolutionFound>;
pub fn execute_benchmark(args: &BenchmarkCli) -> AppResult<String> { pub fn execute_benchmark(args: &BenchmarkCli) -> AppResult<Table> {
let loaded = load_benchmarks(args)?; let loaded = load_benchmarks(args)?;
let benchmarked = loaded.into_iter().map(solve_and_keep_track_of_runtime); let benchmarked = loaded.into_iter().map(solve_and_keep_track_of_runtime);
@ -32,19 +30,18 @@ pub fn execute_benchmark(args: &BenchmarkCli) -> AppResult<String> {
count += 1; count += 1;
}); });
let average = calc_average(sum, count); let average = calc_average(sum, count);
let header = row_building::create_header();
let table: MatrixReport = after_header let mut table = Table::new();
let rows = after_header
.into_iter() .into_iter()
.chain(row_building::create_sum_row(sum)) .chain(row_building::create_sum_row(sum))
.chain(row_building::create_average_row(average)) .chain(row_building::create_average_row(average))
.chain(header) .chain(row_building::create_header());
.collect(); for next_row in rows {
let lines = Colonnade::new(COLUMN_NUMBER, 100) table.add_row(next_row);
.unwrap() }
.tabulate(table)?;
Ok(lines.join("\n")) Ok(table)
} }
fn solve_and_keep_track_of_runtime( fn solve_and_keep_track_of_runtime(

View file

@ -1,8 +1,10 @@
use std::{path::PathBuf, time::Duration}; use std::{borrow::Cow, path::PathBuf, time::Duration};
const AVERAGE: &str = "Average"; const AVERAGE: &str = "Average";
const TOTAL: &str = "total"; const TOTAL: &str = "total";
use prettytable::{color, Row};
use crate::{ use crate::{
benchmarking::ConductedBenchmark, benchmarking::ConductedBenchmark,
cli::{GivenDay, GivenTask}, cli::{GivenDay, GivenTask},
@ -10,16 +12,16 @@ use crate::{
solving_given::NoSolutionFound, solving_given::NoSolutionFound,
}; };
pub const COLUMN_NUMBER: usize = 6; type OptionalContent = Option<Cow<'static, str>>;
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct RowBuilder { pub struct RowBuilder {
day: Option<String>, day: OptionalContent,
task: Option<String>, task: OptionalContent,
taken_time: Option<Duration>, taken_time: OptionalContent,
actual_result: Option<String>, actual_result: OptionalContent,
expected_result: Option<String>, expected_result: OptionalContent,
path_to_input: Option<String>, path_to_input: OptionalContent,
} }
impl From<NoSolutionFound> for RowBuilder { impl From<NoSolutionFound> for RowBuilder {
@ -46,7 +48,16 @@ impl From<ConductedBenchmark> for RowBuilder {
) )
} }
} }
fn into_borrowed_cell(some_thing: &'static str) -> OptionalContent {
Some(Cow::Borrowed(some_thing))
}
fn into_owned_cell(some_thing: impl ToString) -> OptionalContent {
Some(Cow::Owned(some_thing.to_string()))
}
fn into_owned_cell_with<T>(some_thing: T, on_convert: impl Fn(T) -> String) -> OptionalContent {
Some(Cow::Owned(on_convert(some_thing)))
}
impl RowBuilder { impl RowBuilder {
pub fn new( pub fn new(
day: GivenDay, day: GivenDay,
@ -57,17 +68,22 @@ impl RowBuilder {
path: PathBuf, path: PathBuf,
) -> Self { ) -> Self {
Self { Self {
day: Some(day.to_string()), day: into_owned_cell(day),
task: Some(task.to_string()), task: into_owned_cell(task),
taken_time: Some(taken_time), taken_time: into_owned_cell_with(
actual_result: Some(actual_result), taken_time,
expected_result: Some(expected_result), ConductedBenchmark::convert_duration_to_secs_and_mili_txt,
path_to_input: Some(path.to_string_lossy().to_string()), ),
actual_result: into_owned_cell(actual_result),
expected_result: into_owned_cell(expected_result),
path_to_input: into_owned_cell_with(path, |path| path.to_string_lossy().to_string()),
} }
} }
pub fn no_day_found(wrong_day: GivenDay) -> Self { pub fn no_day_found(wrong_day: GivenDay) -> Self {
let day = Some(format!("Solution found for day {}", wrong_day)); let day = into_owned_cell_with(wrong_day, |to_convert| {
format!("Solution found for day {}", to_convert)
});
Self { Self {
day, day,
..Default::default() ..Default::default()
@ -75,8 +91,10 @@ impl RowBuilder {
} }
pub fn no_task_found(right_day: GivenDay, wrong_task: GivenTask) -> Self { pub fn no_task_found(right_day: GivenDay, wrong_task: GivenTask) -> Self {
let day = Some(right_day.to_string()); let day = into_owned_cell(right_day);
let task = Some(format!("No solution found for task {}", wrong_task)); let task = into_owned_cell_with(wrong_task, |to_convert| {
format!("No solution found for task {}", to_convert)
});
Self { Self {
day, day,
task, task,
@ -84,6 +102,17 @@ impl RowBuilder {
} }
} }
pub fn header() -> Self {
Self {
day: into_borrowed_cell("Day"),
task: into_borrowed_cell("Task"),
taken_time: into_borrowed_cell("How long (Seconds:Nano)"),
actual_result: into_borrowed_cell("Actual"),
expected_result: into_borrowed_cell("Expected"),
path_to_input: into_borrowed_cell("Used input file"),
}
}
pub fn average(average: Duration) -> Self { pub fn average(average: Duration) -> Self {
Self::new_aggreate(AVERAGE, average) Self::new_aggreate(AVERAGE, average)
} }
@ -92,28 +121,49 @@ impl RowBuilder {
Self::new_aggreate(TOTAL, total) Self::new_aggreate(TOTAL, total)
} }
pub fn into_row(self) -> Vec<String> { fn this_or_placeholder(value: OptionalContent) -> prettytable::Cell {
fn this_or_placeholder(value: Option<String>) -> String { let value = value.unwrap_or(Cow::Borrowed(constants::PLACEHOLDER_IN_BENCHMARK_REPORTS));
value.unwrap_or_else(|| constants::PLACEHOLDER_IN_BENCHMARK_REPORTS.to_string()) prettytable::Cell::new(&value)
} }
fn color_red_if_non_static_value(actual_result: OptionalContent) -> prettytable::Cell {
let has_different_acutual_than_expected_and_is_no_label = actual_result
.as_ref()
.is_some_and(|might_be_borrow| matches!(might_be_borrow, Cow::Owned(_)));
let tmp = Self::this_or_placeholder(actual_result);
if has_different_acutual_than_expected_and_is_no_label {
tmp.with_style(prettytable::Attr::ForegroundColor(color::RED))
} else {
tmp
}
}
pub fn into_row(self) -> Row {
let might_colored_red_actual = Self::color_red_if_non_static_value(self.actual_result);
let (day, task, taken_time, actual_result, expected_result, path) = ( let (day, task, taken_time, actual_result, expected_result, path) = (
this_or_placeholder(self.day), Self::this_or_placeholder(self.day),
this_or_placeholder(self.task), Self::this_or_placeholder(self.task),
this_or_placeholder( Self::this_or_placeholder(self.taken_time),
self.taken_time might_colored_red_actual,
.map(ConductedBenchmark::convert_duration_to_secs_and_mili_txt), Self::this_or_placeholder(self.expected_result),
), Self::this_or_placeholder(self.path_to_input),
this_or_placeholder(self.actual_result),
this_or_placeholder(self.expected_result),
this_or_placeholder(self.path_to_input),
); );
vec![day, task, taken_time, actual_result, expected_result, path]
prettytable::Row::new(vec![
day,
task,
taken_time,
actual_result,
expected_result,
path,
])
} }
fn new_aggreate(label: &str, aggregate: Duration) -> Self { fn new_aggreate(label: &str, aggregate: Duration) -> Self {
let (day, task) = (Some(label.to_string()), Some(label.to_string())); let (day, task) = (into_owned_cell(label), into_owned_cell(label));
let taken_time = Some(aggregate); let taken_time = into_owned_cell_with(
aggregate,
ConductedBenchmark::convert_duration_to_secs_and_mili_txt,
);
Self { Self {
day, day,
task, task,

View file

@ -1,18 +1,13 @@
pub type MatrixReport = Vec<Vec<String>>; pub type MatrixReport = Vec<Row>;
pub type SingleRow = std::iter::Once<Vec<String>>; pub type SingleRow = std::iter::Once<Row>;
use prettytable::Row;
use super::{row_builder::RowBuilder, BenchmarkResult}; use super::{row_builder::RowBuilder, BenchmarkResult};
use std::time::Duration; use std::time::Duration;
pub fn create_header() -> std::iter::Once<Vec<String>> { pub fn create_header() -> SingleRow {
std::iter::once(vec![ std::iter::once(RowBuilder::header().into_row())
"Day".to_string(),
"Task".to_string(),
"How long (Seconds:Mili)".to_string(),
"Expected".to_string(),
"Actual".to_string(),
"Used input file".to_string(),
])
} }
pub fn create_sum_row(sum: Duration) -> SingleRow { pub fn create_sum_row(sum: Duration) -> SingleRow {

View file

@ -1,3 +1,7 @@
use std::fmt::Display;
use prettytable::Table;
pub mod benchmarking; pub mod benchmarking;
pub mod cli; pub mod cli;
pub mod constants; pub mod constants;
@ -6,3 +10,27 @@ pub mod solving_given;
pub type AppError = anyhow::Error; pub type AppError = anyhow::Error;
pub type AppResult<T = ()> = anyhow::Result<T>; pub type AppResult<T = ()> = anyhow::Result<T>;
#[derive(Debug)]
pub enum AppOutput {
JustString(String),
PrettyTable(Table),
}
impl AppOutput {
pub fn print_std_out(&self) {
match self {
AppOutput::JustString(string) => println!("{}", string),
AppOutput::PrettyTable(table) => table.printstd(),
}
}
}
impl Display for AppOutput {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
AppOutput::JustString(string) => f.write_str(string),
AppOutput::PrettyTable(table) => f.write_str(&table.to_string()),
}
}
}

View file

@ -4,7 +4,7 @@ use advent_of_code_2023::{
benchmarking::execute_benchmark, benchmarking::execute_benchmark,
cli::{AppCliArgs, AppCliSubcommands}, cli::{AppCliArgs, AppCliSubcommands},
solving_given::solve_given_from_cli, solving_given::solve_given_from_cli,
AppResult, AppOutput, AppResult,
}; };
use clap::Parser; use clap::Parser;
@ -14,7 +14,7 @@ fn main() -> ExitCode {
let solution = handle_command(&args); let solution = handle_command(&args);
match solution { match solution {
Ok(found_solution) => { Ok(found_solution) => {
println!("{}", found_solution); found_solution.print_std_out();
ExitCode::SUCCESS ExitCode::SUCCESS
} }
Err(error) => { Err(error) => {
@ -24,9 +24,13 @@ fn main() -> ExitCode {
} }
} }
fn handle_command(args: &AppCliArgs) -> AppResult<String> { fn handle_command(args: &AppCliArgs) -> AppResult<AppOutput> {
match args.sub_command() { match args.sub_command() {
AppCliSubcommands::Solve(to_solve) => solve_given_from_cli(to_solve), AppCliSubcommands::Solve(to_solve) => {
AppCliSubcommands::Benchmark(benchmark) => execute_benchmark(benchmark), solve_given_from_cli(to_solve).map(AppOutput::JustString)
}
AppCliSubcommands::Benchmark(benchmark) => {
execute_benchmark(benchmark).map(AppOutput::PrettyTable)
}
} }
} }

View file

@ -14,6 +14,7 @@ pub fn solve_task_1(input: &str) -> String {
} }
how_many_times_won.to_string() how_many_times_won.to_string()
} }
pub fn solve_task_2(input: &str) -> String { pub fn solve_task_2(input: &str) -> String {
let parsed = parsing::parsing_part_2(input); let parsed = parsing::parsing_part_2(input);