Benchmark reporting;
Build red coloring for actual output if different from expected Removed dependency colon ... with prettytable
This commit is contained in:
parent
a3ce12a80b
commit
603ee1827d
8 changed files with 310 additions and 94 deletions
207
Cargo.lock
generated
207
Cargo.lock
generated
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue