diff --git a/Cargo.lock b/Cargo.lock index 3cc047c..d0f2337 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "argh" version = "0.1.8" @@ -77,9 +68,9 @@ checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" [[package]] name = "bytes" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" [[package]] name = "cassowary" @@ -101,22 +92,31 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "2.34.0" +version = "3.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "a3dbbb6653e7c55cc8595ad3e1f7be8f32aba4eb7ff7f0fd1163d4f3d137c0a9" dependencies = [ - "ansi_term", "atty", "bitflags", + "clap_lex", + "indexmap", "strsim", + "termcolor", "textwrap", - "unicode-width", - "vec_map", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", ] [[package]] name = "conclusive" -version = "0.1.0" +version = "1.0.0" dependencies = [ "argh", "clap", @@ -154,9 +154,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" dependencies = [ "instant", ] @@ -261,9 +261,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "heck" @@ -319,9 +319,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.19" +version = "0.14.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f" +checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" dependencies = [ "bytes", "futures-channel", @@ -398,9 +398,9 @@ checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" [[package]] name = "js-sys" -version = "0.3.58" +version = "0.3.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" +checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" dependencies = [ "wasm-bindgen", ] @@ -502,15 +502,15 @@ checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" [[package]] name = "once_cell" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" +checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" [[package]] name = "openssl" -version = "0.10.40" +version = "0.10.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb81a6430ac911acb25fe5ac8f1d2af1b4ea8a4fdfda0f1ee4292af2e2d8eb0e" +checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0" dependencies = [ "bitflags", "cfg-if", @@ -540,9 +540,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.74" +version = "0.9.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "835363342df5fba8354c5b453325b110ffd54044e588c539cf2f20a8014e4cb1" +checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f" dependencies = [ "autocfg", "cc", @@ -551,6 +551,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "os_str_bytes" +version = "6.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4" + [[package]] name = "parking_lot" version = "0.12.1" @@ -600,9 +606,9 @@ checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "proc-macro2" -version = "1.0.40" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" +checksum = "c278e965f1d8cf32d6e0e96de3d3e79712178ae67986d9cf9151f51e95aac89b" dependencies = [ "unicode-ident", ] @@ -618,9 +624,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] @@ -727,18 +733,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.137" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.137" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da" dependencies = [ "proc-macro2", "quote", @@ -779,9 +785,12 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] [[package]] name = "smallvec" @@ -801,9 +810,9 @@ dependencies = [ [[package]] name = "strsim" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" @@ -830,6 +839,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + [[package]] name = "termion" version = "1.5.6" @@ -844,12 +862,9 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.11.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "tinyvec" @@ -868,10 +883,11 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.19.2" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439" +checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581" dependencies = [ + "autocfg", "bytes", "libc", "memchr", @@ -929,9 +945,9 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" +checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" dependencies = [ "cfg-if", "pin-project-lite", @@ -940,9 +956,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7" +checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" dependencies = [ "once_cell", ] @@ -955,9 +971,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "tui" -version = "0.14.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ced152a8e9295a5b168adc254074525c17ac4a83c90b2716274cc38118bddc9" +checksum = "96fe69244ec2af261bced1d9046a6fee6c8c2a6b0228e59e5ba39bc8ba4ed729" dependencies = [ "bitflags", "cassowary", @@ -974,15 +990,15 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" +checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7" [[package]] name = "unicode-normalization" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dee68f85cab8cf68dec42158baf3a79a1cdc065a8b103025965d6ccb7f6cbd" +checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" dependencies = [ "tinyvec", ] @@ -1017,12 +1033,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "want" version = "0.3.0" @@ -1041,9 +1051,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.81" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" +checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1051,13 +1061,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.81" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" +checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" dependencies = [ "bumpalo", - "lazy_static", "log", + "once_cell", "proc-macro2", "quote", "syn", @@ -1066,9 +1076,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.31" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de9a9cec1733468a8c657e57fa2413d2ae2c0129b95e87c5b72b8ace4d13f31f" +checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" dependencies = [ "cfg-if", "js-sys", @@ -1078,9 +1088,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.81" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" +checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1088,9 +1098,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.81" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" +checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" dependencies = [ "proc-macro2", "quote", @@ -1101,15 +1111,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.81" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" +checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" [[package]] name = "web-sys" -version = "0.3.58" +version = "0.3.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90" +checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" dependencies = [ "js-sys", "wasm-bindgen", @@ -1131,6 +1141,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index 1dd52d2..6eb8c16 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "conclusive" description = "A command line client for Plausible Analytics" -version = "0.1.0" +version = "1.0.0" authors = ["マリウス "] license = "GPL-3.0" edition = "2018" @@ -12,10 +12,10 @@ keywords = ["cli", "tui", "plausible", "analytics", "tool"] categories = ["command-line-utilities"] [dependencies] -tui = "0.14" +tui = { version = "0.18", default-features = false, features = ['termion'] } termion = "1.5" -argh = "0.1.4" +argh = "0.1.8" reqwest = { version = "0.11", features = ["blocking", "json"] } tokio = { version = "1", features = ["full"] } serde = { version = "1.0", features = ["derive"] } -clap = "2.33.3" +clap = "3.2.16" diff --git a/src/main.rs b/src/main.rs index ae31f81..2aca57a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -54,6 +54,19 @@ struct TopSourceResult { visitors: Option, } +#[derive(Deserialize, Debug)] +struct AggregateValue { + value: Option, +} + +#[derive(Deserialize, Debug)] +struct AggregateResult { + bounce_rate: AggregateValue, + pageviews: AggregateValue, + visit_duration: AggregateValue, + visitors: AggregateValue, +} + #[derive(Deserialize, Debug)] struct TimeseriesResult { date: String, @@ -62,7 +75,7 @@ struct TimeseriesResult { #[derive(Deserialize, Debug)] struct ApiResponse { - results: Vec, + results: T, } pub struct TUI<'a> { @@ -106,17 +119,31 @@ fn main() .takes_value(true)) .arg(Arg::with_name("period") .help("Period") - .short("p") + .short('p') .long("period") .takes_value(true)) .get_matches(); let site_id = args.value_of("SITE-ID").unwrap(); - let period = args.value_of("period").unwrap_or("7d"); + let period = args.value_of("period").unwrap_or("30d"); let plausible_token = env::var("PLAUSIBLE_TOKEN").unwrap(); - let timeseries: ApiResponse = + let aggregate: ApiResponse = + match req(&format!( + "{api}/aggregate?site_id={site_id}&period={period}&metrics=visitors,pageviews,bounce_rate,visit_duration", + api = API_BASE_URL, + site_id = site_id, + period = period + ), &plausible_token) { + Err(e) => { + println!("Error: {:#?}", e); + std::process::exit(1); + }, + Ok(r) => r, + }; + + let timeseries: ApiResponse> = match req(&format!( "{api}/timeseries?site_id={site_id}&period={period}", api = API_BASE_URL, @@ -130,13 +157,13 @@ fn main() Ok(r) => r, }; - let top_sources: ApiResponse = + let top_sources: ApiResponse> = match req(&format!( "{api}/breakdown?site_id={site_id}&period={period}&{args}", api = API_BASE_URL, site_id = site_id, period = period, - args = "property=visit:source&metrics=visitors,bounce_rate&limit=5" + args = "property=visit:source&metrics=visitors,bounce_rate&limit=10" ), &plausible_token) { Err(e) => { println!("Error: {:#?}", e); @@ -145,13 +172,13 @@ fn main() Ok(r) => r, }; - let top_pages: ApiResponse = + let top_pages: ApiResponse> = match req(&format!( "{api}/breakdown?site_id={site_id}&period={period}&{args}", api = API_BASE_URL, site_id = site_id, period = period, - args = "property=event:page&metrics=visitors,bounce_rate&limit=5" + args = "property=event:page&metrics=visitors,bounce_rate&limit=10" ), &plausible_token) { Err(e) => { println!("Error: {:#?}", e); @@ -161,13 +188,11 @@ fn main() }; let mut stats: Vec<(&str, u64)> = Vec::new(); - let mut total_visitors: u64 = 0; for result in timeseries.results.iter() { let len = result.date.len(); let visitors: u64 = result.visitors.unwrap_or(0); stats.push((&result.date[len-2..], visitors)); - total_visitors += visitors; } println!("{:#?}", stats); @@ -179,7 +204,7 @@ fn main() let app = TUI::new(stats); terminal.clear()?; - terminal.draw(|f| { + let _drawn = match terminal.draw(|f| { let chunks = Layout::default() .direction(Direction::Vertical) .margin(1) @@ -205,22 +230,75 @@ fn main() ) .split(chunks[0]); - let block_overview_unique_visitors = Block::default() + // Total Visitors + let block_overview_visitors = Block::default() .title("Total Visitors") .borders(Borders::ALL); - let overview_text = vec![ + let overview_visitors_text = vec![ + Spans::from(""), + Spans::from(format!("{total_visitors}", total_visitors = aggregate.results.visitors.value.unwrap_or(0))) + ]; + + let overview_visitors = Paragraph::new(overview_visitors_text) + .style(Style::default()) + .block(block_overview_visitors) + .alignment(Alignment::Center); + + f.render_widget(overview_visitors, layout_overview[0]); + + // Total Pageviews + let block_overview_pageviews = Block::default() + .title("Total Pageviews") + .borders(Borders::ALL); + + let overview_pageviews_text = vec![ + Spans::from(""), + Spans::from(format!("{total_pageviews}", total_pageviews = aggregate.results.pageviews.value.unwrap_or(0))) + ]; + + let overview_pageviews = Paragraph::new(overview_pageviews_text) + .style(Style::default()) + .block(block_overview_pageviews) + .alignment(Alignment::Center); + + f.render_widget(overview_pageviews, layout_overview[1]); + + // Bounce Rate + let block_overview_bounce = Block::default() + .title("Bounce Rate") + .borders(Borders::ALL); + + let overview_bounce_text = vec![ Spans::from(""), - Spans::from(format!("{total_visitors}", total_visitors = total_visitors)) + Spans::from(format!("{bounce_rate}%", bounce_rate = aggregate.results.bounce_rate.value.unwrap_or(0))) ]; - let overview = Paragraph::new(overview_text) + let overview_bounce = Paragraph::new(overview_bounce_text) .style(Style::default()) - .block(block_overview_unique_visitors) + .block(block_overview_bounce) .alignment(Alignment::Center); - f.render_widget(overview, layout_overview[0]); + f.render_widget(overview_bounce, layout_overview[2]); + // Visit Duration + let block_overview_duration = Block::default() + .title("Visit Duration") + .borders(Borders::ALL); + + let overview_duration_text = vec![ + Spans::from(""), + Spans::from(format!("{visit_duration}s", visit_duration = aggregate.results.visit_duration.value.unwrap_or(0))) + ]; + + let overview_duration = Paragraph::new(overview_duration_text) + .style(Style::default()) + .block(block_overview_duration) + .alignment(Alignment::Center); + + f.render_widget(overview_duration, layout_overview[3]); + + // Bar Chart let barchart = BarChart::default() .block(Block::default().borders(Borders::ALL).title("Stats")) .data(&app.stats) @@ -286,14 +364,14 @@ fn main() .height(1) .bottom_margin(1); let rows2 = top_pages.results.iter().map(|item| { - let cells = vec![ + let cells2 = vec![ Cell::from(format!("{}", item.visitors.unwrap_or(0))), Cell::from(format!("{}", item.page)), Cell::from(format!("{}%", item.bounce_rate.unwrap_or(0.0))) ]; - Row::new(cells).height(1 as u16).bottom_margin(1) + Row::new(cells2).height(1 as u16).bottom_margin(1) }); - let t = Table::new(rows2) + let t2 = Table::new(rows2) .header(header2) .block(Block::default().borders(Borders::ALL).title("Top Pages")) .widths(&[ @@ -301,7 +379,10 @@ fn main() Constraint::Min(16), Constraint::Length(5), ]); - f.render_widget(t, chunks2[1]); - }) + f.render_widget(t2, chunks2[1]); + }) { + Ok(_) => return Ok(()), + Err(e) => return Err(e), + }; }