added utf8 test to asciifyed image only in debug

renamed print_table macro identifyers
added some docs
added none_if_empty macro
get_image now returns String instead of Vec<u8>
This commit is contained in:
LordMZTE 2020-09-29 15:05:15 +02:00
parent 82f620600f
commit ebe59d3195
2 changed files with 56 additions and 22 deletions

View file

@ -1,24 +1,37 @@
use asciify::AsciiBuilder; use asciify::AsciiBuilder;
/// prints a table with the entries supplied
/// the identifier at the start of each entry sets the type
///
/// l = list entry
/// b = block
/// lo = list entry option
/// bo = block option
///
/// options are checked if they are `Some` and won't be printed if they aren't
#[macro_export] #[macro_export]
macro_rules! print_table { macro_rules! print_table {
(s $l:expr => $k:expr) => { //list entry
(l $l:expr => $k:expr) => {
println!("{: <20} | {}", $l, $k); println!("{: <20} | {}", $l, $k);
}; };
(m $l:expr => $k:expr) => { //block
(b $l:expr => $k:expr) => {
println!("{:=^25}\n{}\n=========================\n", $l, $k); println!("{:=^25}\n{}\n=========================\n", $l, $k);
}; };
(se $l:expr => $k:expr) => { //list entry option
if !&$k.is_empty() { (lo $l:expr => $k:expr) => {
println!("{: <20} | {}", $l, $k); if let Some(txt) = $k {
println!("{: <20} | {}", $l, txt);
} }
}; };
(me $l:expr => $k:expr) => { //block option
if !&$k.is_empty() { (bo $l:expr => $k:expr) => {
println!("{:=^25}\n{}\n=========================\n", $l, $k); if let Some(txt) = $k {
println!("{:=^25}\n{}\n=========================\n", $l, txt);
} }
}; };
@ -27,6 +40,20 @@ macro_rules! print_table {
}; };
} }
/// returns an `Option` of the expression passed in
/// `None` if the `is_empty` on the expression returns true, `Some(x)` otherwise
/// this is a macro and not a function because `is_empty` is not defined in any trait
#[macro_export]
macro_rules! none_if_empty {
($x:expr) => {
if $x.is_empty() {
None
} else {
Some($x)
}
};
}
pub struct AsciiConfig { pub struct AsciiConfig {
pub size: Option<u32>, pub size: Option<u32>,
pub colored: bool, pub colored: bool,

View file

@ -5,7 +5,7 @@ extern crate mcstat;
#[macro_use] #[macro_use]
extern crate anyhow; extern crate anyhow;
use std::io::{Cursor, Write}; use std::io::Cursor;
use time::Duration; use time::Duration;
use tokio::time; use tokio::time;
@ -105,26 +105,24 @@ async fn main() -> Result<()> {
.collect::<String>(); .collect::<String>();
print_table! { print_table! {
me "Description" => remove_formatting(&response.description.text), bo "Description" => none_if_empty!(remove_formatting(&response.description.text)),
me "Player Sample" => remove_formatting(&player_sample), bo "Player Sample" => none_if_empty!(remove_formatting(&player_sample)),
se "Server Version" => remove_formatting(&response.version.name), lo "Server Version" => none_if_empty!(remove_formatting(&response.version.name)),
s "Online Players" => response.players.online, l "Online Players" => response.players.online,
s "Max Players" => response.players.max, l "Max Players" => response.players.max,
s "Server Protocol" => response.version.protocol, l "Server Protocol" => response.version.protocol,
}; };
if let Some(img) = image { if let Some(img) = image {
let stdout = std::io::stdout(); println!("\n{}", img.await??);
let mut handle = stdout.lock();
handle.write_all(&[b'\n'])?;
handle.write_all(&img.await??)?;
} }
//endregion //endregion
Ok(()) Ok(())
} }
/// returns the asciifyed image as UTF-8 bytes /// returns the asciifyed image from base64
async fn get_image(favicon: String, config: AsciiConfig) -> Result<Vec<u8>> { /// returns Err if the base64 image is invalid
async fn get_image(favicon: String, config: AsciiConfig) -> Result<String> {
let img = image_base64::from_base64(favicon); let img = image_base64::from_base64(favicon);
let image = let image =
image::load(Cursor::new(img), ImageFormat::Png).context("favicon has invalid format")?; image::load(Cursor::new(img), ImageFormat::Png).context("favicon has invalid format")?;
@ -142,5 +140,14 @@ async fn get_image(favicon: String, config: AsciiConfig) -> Result<Vec<u8>> {
buf buf
}; };
buf.reset()?; buf.reset()?;
Ok(buf.as_slice().to_vec())
let bytes = buf.as_slice().to_vec();
//only check utf8 format in debug mode
#[cfg(debug_assertions)]
let out = String::from_utf8(bytes).expect("asciifyed image is invalid utf8");
#[cfg(not(debug_assertions))]
let out = unsafe { String::from_utf8_unchecked(bytes) };
Ok(out)
} }