mirror of
https://github.com/LordMZTE/mcstat.git
synced 2024-05-14 21:09:45 +02:00
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:
parent
82f620600f
commit
ebe59d3195
43
src/lib.rs
43
src/lib.rs
|
@ -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,
|
||||||
|
|
35
src/main.rs
35
src/main.rs
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue