[Add] Console Features, QOL

This commit is contained in:
Alex Emmet 2026-02-19 22:58:22 +01:00
commit faf60b144a
11 changed files with 707 additions and 560 deletions

View file

@ -1,19 +1,32 @@
use actix_web::web::block; use crossterm::event::{KeyCode, KeyEvent};
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; use json::JsonValue;
use ratatui::{ use ratatui::{
Frame, Frame,
layout::{Alignment, Constraint, Layout, Rect}, layout::Rect,
style::{Color, Style}, style::{Color, Style},
text::{Line, Span}, text::{Line, Span},
widgets::{Block, Borders, Paragraph}, widgets::{Block, Borders, Paragraph},
}; };
use crate::gui::{ use crate::{
elements::elements::{Element, InteractableElement, JoinableElement}, ACTIVE_TASKS,
interaction_result::InteractionResult, data::communication::{CommunicationType, CommunicationValue, DataTypes},
util::borders::draw_block_joins, gui::{
elements::elements::{Element, InteractableElement, JoinableElement},
interaction_result::InteractionResult,
ui::{FPS, UI},
util::borders::draw_block_joins,
},
log, log_cv,
omikron::omikron_connection::OMIKRON_CONNECTION,
users::{user_manager, user_profile::UserProfile},
util::file_util,
};
use std::{
any::Any,
sync::Arc,
time::{Duration, SystemTime},
}; };
use std::any::Any;
pub struct ConsoleCard { pub struct ConsoleCard {
focused: bool, focused: bool,
@ -115,6 +128,10 @@ impl InteractableElement for ConsoleCard {
fn interact(&mut self, key: KeyEvent) -> InteractionResult { fn interact(&mut self, key: KeyEvent) -> InteractionResult {
match key.code { match key.code {
KeyCode::Enter => { KeyCode::Enter => {
let command = self.content.clone();
tokio::spawn(async move {
run_command(&command).await;
});
self.content = "".to_string(); self.content = "".to_string();
InteractionResult::Handled InteractionResult::Handled
} }
@ -145,3 +162,114 @@ impl InteractableElement for ConsoleCard {
self.focused = f; self.focused = f;
} }
} }
pub async fn run_command(command: &str) {
log!(":{}", command);
let parts = command.split(" ").collect::<Vec<&str>>();
match parts.as_slice() {
["tasks"] => {
let active_tasks: Vec<String> =
ACTIVE_TASKS.clone().iter().map(|v| v.to_string()).collect();
log!("Active tasks: {:?}", active_tasks);
}
["fps"] => {
log!("FPS: {}", *FPS.read().await);
}
["ping"] => {
let time = 20;
let now = SystemTime::now();
let conn = {
let guard = OMIKRON_CONNECTION.read().await;
guard.as_ref().cloned()
};
let conn = match conn {
Some(c) => c,
None => return,
};
let response_cv = conn
.await_response(
&CommunicationValue::new(CommunicationType::ping),
Some(Duration::from_secs(time)),
)
.await;
let elapsed = now.elapsed().unwrap_or(Duration::ZERO);
match response_cv {
Ok(response) => log_cv!(response.add_data(
DataTypes::get_time,
JsonValue::from(elapsed.as_millis() as i64)
)),
Err(err) => log!("Ping error: {:?}", err),
}
}
["ping", time] => {
let time = time.parse::<u64>().unwrap_or(20);
let conn = {
let guard = OMIKRON_CONNECTION.read().await;
guard.as_ref().cloned()
};
let conn = match conn {
Some(c) => c,
None => return,
};
let response_cv = conn
.await_response(
&CommunicationValue::new(CommunicationType::ping),
Some(Duration::from_secs(time)),
)
.await;
match response_cv {
Ok(response) => log_cv!(response),
Err(err) => log!("Ping error: {:?}", err),
}
}
["user", "add", username] => {
if let (Some(user), Some(_)) = user_manager::create_user(username).await {
log!("Created user {}", user.user_id);
} else {
log!("Failed to create user");
}
}
["user", "remove", username] => {
if let Some(user) = user_manager::get_user_by_username(username) {
user_manager::remove_user(user.user_id);
log!("Removed user {}", user.user_id);
} else {
log!("Failed to find user");
}
}
["user", "list"] => {
let users: Vec<UserProfile> = user_manager::get_users();
for user in users {
let storage = file_util::get_designed_storage(user.user_id);
log!(
"> Username: {}, ID: {}, created at: {}, storage: {}",
user.username,
user.user_id,
user.created_at,
storage
);
}
}
["user", "info", username] => {
if let Some(user) = user_manager::get_user_by_username(username) {
user_manager::remove_user(user.user_id);
log!("Removed user {}", user.user_id);
} else {
log!("Failed to find user");
}
}
_ => {
log!("Unknown command");
}
}
}

View file

@ -7,10 +7,7 @@ use std::time::Duration;
pub fn setup_input_handler(ui: Arc<UI>) { pub fn setup_input_handler(ui: Arc<UI>) {
tokio::spawn(async move { tokio::spawn(async move {
ACTIVE_TASKS ACTIVE_TASKS.insert("Input Handler".to_string());
.lock()
.unwrap()
.push("Input Handler".to_string());
loop { loop {
{ {
@ -42,8 +39,7 @@ pub fn setup_input_handler(ui: Arc<UI>) {
} }
} }
{ {
let mut tasks = ACTIVE_TASKS.lock().unwrap(); ACTIVE_TASKS.remove("Input Handler");
tasks.retain(|t| t != "Input Handler");
} }
}); });
} }

View file

@ -1,7 +1,7 @@
use crate::gui::{ use crate::gui::{
elements::{ elements::{
console_card::ConsoleCard, console_card::ConsoleCard,
elements::{Element, InteractableElement, JoinableElement}, elements::{InteractableElement, JoinableElement},
log_card::LogCard, log_card::LogCard,
}, },
interaction_result::InteractionResult, interaction_result::InteractionResult,

View file

@ -1,5 +1,5 @@
use crate::{ use crate::{
SHUTDOWN, ACTIVE_TASKS, SHUTDOWN,
gui::{ gui::{
input_handler::setup_input_handler, interaction_result::InteractionResult, input_handler::setup_input_handler, interaction_result::InteractionResult,
screens::screens::Screen, screens::screens::Screen,
@ -13,10 +13,12 @@ use std::{
sync::{Arc, Mutex}, sync::{Arc, Mutex},
time::Duration, time::Duration,
}; };
use tokio::sync::RwLock; use tokio::{sync::RwLock, time::Instant};
/// UI state and rendering /// UI state and rendering
pub static UNIQUE: Lazy<RwLock<bool>> = Lazy::new(|| RwLock::new(true)); pub static UNIQUE: Lazy<RwLock<bool>> = Lazy::new(|| RwLock::new(true));
pub static FPS: Lazy<RwLock<f64>> = Lazy::new(|| RwLock::new(0.0));
pub struct UI { pub struct UI {
pub terminal: Arc<Mutex<Terminal<CrosstermBackend<Stdout>>>>, pub terminal: Arc<Mutex<Terminal<CrosstermBackend<Stdout>>>>,
screen: Arc<RwLock<Option<Box<dyn Screen>>>>, screen: Arc<RwLock<Option<Box<dyn Screen>>>>,
@ -26,6 +28,9 @@ pub fn start_tui() -> Arc<UI> {
let ui = Arc::new(UI::new()); let ui = Arc::new(UI::new());
let uic = ui.clone(); let uic = ui.clone();
tokio::spawn(async move { tokio::spawn(async move {
ACTIVE_TASKS.insert("UI Renderer".to_string());
let mut last_render = Instant::now();
let mut last: Vec<f64> = Vec::new();
loop { loop {
if *SHUTDOWN.read().await { if *SHUTDOWN.read().await {
break; break;
@ -33,10 +38,19 @@ pub fn start_tui() -> Arc<UI> {
if *UNIQUE.read().await { if *UNIQUE.read().await {
uic.render().await; uic.render().await;
} else { let elapsed = last_render.elapsed().as_secs_f64();
tokio::time::sleep(Duration::from_millis(50)).await; if elapsed > 0.0 {
last.push(1.0 / elapsed);
}
if last.len() > 10 {
last.remove(0);
}
*FPS.write().await = last.iter().sum::<f64>() / last.len() as f64;
last_render = Instant::now();
} }
tokio::time::sleep(Duration::from_millis(16)).await;
} }
ACTIVE_TASKS.remove("UI Renderer");
ratatui::restore(); ratatui::restore();
}); });
setup_input_handler(ui.clone()); setup_input_handler(ui.clone());

View file

@ -1,3 +1,4 @@
use dashmap::DashSet;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use pnet::datalink::NetworkInterface; use pnet::datalink::NetworkInterface;
use std::sync::Arc; use std::sync::Arc;
@ -37,7 +38,7 @@ pub static APP_STATE: LazyLock<Arc<Mutex<AppState>>> =
pub static SHUTDOWN: Lazy<RwLock<bool>> = Lazy::new(|| RwLock::new(false)); pub static SHUTDOWN: Lazy<RwLock<bool>> = Lazy::new(|| RwLock::new(false));
pub static RELOAD: Lazy<RwLock<bool>> = Lazy::new(|| RwLock::new(true)); pub static RELOAD: Lazy<RwLock<bool>> = Lazy::new(|| RwLock::new(true));
pub static ACTIVE_TASKS: Lazy<Mutex<Vec<String>>> = Lazy::new(|| Mutex::new(Vec::new())); pub static ACTIVE_TASKS: Lazy<DashSet<String>> = Lazy::new(|| DashSet::new());
#[tokio::main(flavor = "multi_thread", worker_threads = 8)] #[tokio::main(flavor = "multi_thread", worker_threads = 8)]
#[allow(unused_must_use, dead_code)] #[allow(unused_must_use, dead_code)]
@ -48,20 +49,12 @@ async fn main() {
let ui = start_tui(); let ui = start_tui();
let ui_clone = ui.clone();
tokio::spawn(async move {
loop {
ui_clone.render().await;
sleep(Duration::from_millis(16)).await;
}
});
let (eula, tos_pp) = consent_state::check(ui.clone()).await; let (eula, tos_pp) = consent_state::check(ui.clone()).await;
if !eula { if !eula {
*SHUTDOWN.write().await = true; *SHUTDOWN.write().await = true;
loop { loop {
if ACTIVE_TASKS.lock().unwrap().is_empty() { if ACTIVE_TASKS.is_empty() {
break; break;
} }
sleep(Duration::from_secs(1)).await; sleep(Duration::from_secs(1)).await;
@ -73,7 +66,7 @@ async fn main() {
if !tos_pp { if !tos_pp {
*SHUTDOWN.write().await = true; *SHUTDOWN.write().await = true;
loop { loop {
if ACTIVE_TASKS.lock().unwrap().is_empty() { if ACTIVE_TASKS.is_empty() {
break; break;
} }
sleep(Duration::from_millis(100)).await; sleep(Duration::from_millis(100)).await;
@ -171,8 +164,10 @@ async fn main() {
} }
let omikron: Arc<OmikronConnection> = Arc::new(OmikronConnection::new()); let omikron: Arc<OmikronConnection> = Arc::new(OmikronConnection::new());
omikron.connect().await; omikron.connect().await;
let mut omikron_connection = OMIKRON_CONNECTION.write().await; {
*omikron_connection = Some(omikron.clone()); let mut omikron_connection = OMIKRON_CONNECTION.write().await;
*omikron_connection = Some(omikron.clone());
}
log_t!("setup_completed"); log_t!("setup_completed");
loop { loop {
if *SHUTDOWN.read().await { if *SHUTDOWN.read().await {
@ -186,7 +181,7 @@ async fn main() {
} }
if *RELOAD.read().await { if *RELOAD.read().await {
loop { loop {
if ACTIVE_TASKS.lock().unwrap().is_empty() { if ACTIVE_TASKS.is_empty() {
break; break;
} }
sleep(Duration::from_secs(1)).await; sleep(Duration::from_secs(1)).await;

File diff suppressed because it is too large Load diff

View file

@ -66,9 +66,9 @@ pub async fn start(port: u16) -> bool {
let server_handle = server.handle(); let server_handle = server.handle();
tx.send(server_handle).unwrap(); tx.send(server_handle).unwrap();
ACTIVE_TASKS.lock().unwrap().push("WebServer".into()); ACTIVE_TASKS.insert("WebServer".into());
server.await.unwrap(); server.await.unwrap();
ACTIVE_TASKS.lock().unwrap().retain(|t| t != "WebServer"); ACTIVE_TASKS.remove("WebServer");
log!("Web Server shutdown complete."); log!("Web Server shutdown complete.");
}); });

View file

@ -1,5 +1,4 @@
use actix_web::{HttpRequest, HttpResponse, web}; use actix_web::{HttpRequest, HttpResponse};
use json::JsonValue;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use crate::util::file_util::load_file_vec; use crate::util::file_util::load_file_vec;
@ -17,32 +16,21 @@ fn codec_for_ext(ext: &str) -> &'static str {
} }
} }
pub async fn handle(req: HttpRequest, body: web::Bytes) -> HttpResponse { pub async fn handle(req: HttpRequest) -> HttpResponse {
// Optional JSON parsing
let _body_json: Option<JsonValue> = if !body.is_empty() {
json::parse(std::str::from_utf8(&body).unwrap_or("")).ok()
} else {
None
};
let req_path = req.path().trim_start_matches('/'); let req_path = req.path().trim_start_matches('/');
// 1⃣ Resolve the filesystem path
let mut fs_path = PathBuf::from("web"); let mut fs_path = PathBuf::from("web");
// Boolean P: no path provided → redirect to index.html
if req_path.is_empty() { if req_path.is_empty() {
fs_path.push("index.html"); fs_path.push("index.html");
} else { } else {
fs_path.extend(req_path.split('/')); fs_path.extend(req_path.split('/'));
} }
// Boolean D: path is directory → serve index.html inside
if fs_path.is_dir() { if fs_path.is_dir() {
fs_path.push("index.html"); fs_path.push("index.html");
} }
// Boolean E: extension provided
let ext_opt = fs_path.extension().and_then(|e| e.to_str()); let ext_opt = fs_path.extension().and_then(|e| e.to_str());
let mut final_name = fs_path let mut final_name = fs_path
.file_name() .file_name()
@ -51,7 +39,6 @@ pub async fn handle(req: HttpRequest, body: web::Bytes) -> HttpResponse {
.to_string(); .to_string();
if ext_opt.is_none() { if ext_opt.is_none() {
// No extension provided → try HTML
if final_name.is_empty() { if final_name.is_empty() {
final_name = "index.html".to_string(); final_name = "index.html".to_string();
} else { } else {
@ -68,12 +55,10 @@ pub async fn handle(req: HttpRequest, body: web::Bytes) -> HttpResponse {
let dir = fs_path.parent().unwrap_or(Path::new("web")); let dir = fs_path.parent().unwrap_or(Path::new("web"));
// 2⃣ Try to load the resolved file
match load_file_vec(dir.to_str().unwrap_or("web"), &final_name) { match load_file_vec(dir.to_str().unwrap_or("web"), &final_name) {
Ok(content) => HttpResponse::Ok().content_type(content_type).body(content), Ok(content) => HttpResponse::Ok().content_type(content_type).body(content),
Err(_) => { Err(_) => {
// For static assets, return plain 404
let ext = fs_path.extension().and_then(|e| e.to_str()).unwrap_or(""); let ext = fs_path.extension().and_then(|e| e.to_str()).unwrap_or("");
if matches!(ext, "js" | "css" | "woff2") { if matches!(ext, "js" | "css" | "woff2") {
return HttpResponse::NotFound() return HttpResponse::NotFound()
@ -81,7 +66,6 @@ pub async fn handle(req: HttpRequest, body: web::Bytes) -> HttpResponse {
.body("Not found"); .body("Not found");
} }
// 3⃣ Try to serve 404.html from web folder
let fallback = load_file_vec("web", "404.html") let fallback = load_file_vec("web", "404.html")
.unwrap_or_else(|_| include_bytes!("../../static/web/404.html").to_vec()); .unwrap_or_else(|_| include_bytes!("../../static/web/404.html").to_vec());

View file

@ -1,10 +1,11 @@
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes}; use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
use crate::log;
use crate::omikron::omikron_connection::{OMIKRON_CONNECTION, OmikronConnection}; use crate::omikron::omikron_connection::{OMIKRON_CONNECTION, OmikronConnection};
use crate::users::user_profile::UserProfile; use crate::users::user_profile::UserProfile;
use crate::util::crypto_helper::{self, public_key_to_base64}; use crate::util::crypto_helper::{self, public_key_to_base64};
use crate::util::file_util::{load_file, save_file}; use crate::util::file_util::{load_file, save_file};
use crate::util::logger::PrintType;
use crate::{RELOAD, SHUTDOWN}; use crate::{RELOAD, SHUTDOWN};
use crate::{log, log_cv};
use base64::{Engine as _, engine::general_purpose::STANDARD}; use base64::{Engine as _, engine::general_purpose::STANDARD};
use hex::{self}; use hex::{self};
use json::JsonValue; use json::JsonValue;
@ -47,26 +48,37 @@ pub async fn load_from_tu(username: &str) -> Result<(), ()> {
USERS.lock().unwrap().push(user_profile); USERS.lock().unwrap().push(user_profile);
Ok(()) Ok(())
} }
pub async fn create_user(username: &str) -> (Option<UserProfile>, Option<String>) { pub async fn create_user(username: &str) -> (Option<UserProfile>, Option<String>) {
let omikron_con: Arc<OmikronConnection> = let register_cv = CommunicationValue::new(CommunicationType::get_register);
OMIKRON_CONNECTION.read().await.as_ref().unwrap().clone();
let register_cv = if let Ok(register_cv) = omikron_con let conn = {
.clone() let guard = OMIKRON_CONNECTION.read().await;
.await_response( guard.as_ref().cloned()
&CommunicationValue::new(CommunicationType::get_register), };
Some(Duration::from_secs(20)),
) let conn = match conn {
Some(c) => c,
None => return (None, None),
};
let response_cv = match conn
.await_response(&register_cv, Some(Duration::from_secs(20)))
.await .await
{ {
register_cv Ok(cv) => cv,
} else { Err(_) => return (None, None),
return (None, None);
}; };
let user_id = register_cv log_cv!(PrintType::Omega, response_cv);
.get_data(DataTypes::register_id)
let user_id = match response_cv
.get_data(DataTypes::user_id)
.unwrap_or(&JsonValue::Null) .unwrap_or(&JsonValue::Null)
.as_i64() .as_i64()
.unwrap_or(0); {
Some(id) => id,
None => return (None, None),
};
let mut buf = [0u8; 56]; let mut buf = [0u8; 56];
let mut rng = OsRng; let mut rng = OsRng;
rng.fill_bytes(&mut buf); rng.fill_bytes(&mut buf);
@ -101,10 +113,22 @@ pub async fn create_user(username: &str) -> (Option<UserProfile>, Option<String>
.add_data(DataTypes::iota_id, JsonValue::Number(Number::from(user_id))) .add_data(DataTypes::iota_id, JsonValue::Number(Number::from(user_id)))
.add_data(DataTypes::reset_token, JsonValue::String(reset_token)); .add_data(DataTypes::reset_token, JsonValue::String(reset_token));
let response_cv = omikron_con let conn = {
let guard = OMIKRON_CONNECTION.read().await;
guard.as_ref().cloned()
};
let conn = match conn {
Some(c) => c,
None => return (None, None),
};
let response_cv = conn
.await_response(&cv, Some(Duration::from_secs(20))) .await_response(&cv, Some(Duration::from_secs(20)))
.await; .await;
if let Ok(resp) = response_cv { if let Ok(resp) = response_cv {
log_cv!(PrintType::Omega, resp);
if !resp.is_type(CommunicationType::success) { if !resp.is_type(CommunicationType::success) {
return (None, None); return (None, None);
} }
@ -125,6 +149,15 @@ pub async fn create_user(username: &str) -> (Option<UserProfile>, Option<String>
(Some(up), Some(STANDARD.encode(&private_key.as_bytes()))) (Some(up), Some(STANDARD.encode(&private_key.as_bytes())))
} }
pub fn get_user_by_username(username: &str) -> Option<UserProfile> {
USERS
.lock()
.unwrap()
.iter()
.cloned()
.find(|u| u.username == username)
}
pub fn get_user(user_id: i64) -> Option<UserProfile> { pub fn get_user(user_id: i64) -> Option<UserProfile> {
USERS USERS
.lock() .lock()

View file

@ -34,7 +34,7 @@ fn delete_dir_recursive(directory: &Path) -> bool {
} }
#[allow(dead_code)] #[allow(dead_code)]
pub fn delete_user_directory(user_id: Uuid) { pub fn delete_user_directory(user_id: i64) {
let user_dir = Path::new(&get_directory()) let user_dir = Path::new(&get_directory())
.join("users") .join("users")
.join(user_id.to_string()); .join(user_id.to_string());
@ -189,7 +189,7 @@ pub fn get_directory_size(directory: &Path) -> u64 {
} }
#[allow(dead_code)] #[allow(dead_code)]
pub fn get_designed_storage(user_id: Uuid) -> String { pub fn get_designed_storage(user_id: i64) -> String {
let user_dir = Path::new(&get_directory()) let user_dir = Path::new(&get_directory())
.join("users") .join("users")
.join(user_id.to_string()); .join(user_id.to_string());

View file

@ -30,7 +30,7 @@ pub enum PrintType {
struct LogMessage { struct LogMessage {
timestamp_ms: u128, timestamp_ms: u128,
prefix: &'static str, prefix: String,
kind: PrintType, kind: PrintType,
is_error: bool, is_error: bool,
@ -116,7 +116,7 @@ fn fixed_box(content: &str, width: usize) -> String {
pub fn log_internal_translated( pub fn log_internal_translated(
kind: PrintType, kind: PrintType,
prefix: &'static str, prefix: String,
is_error: bool, is_error: bool,
key: &str, key: &str,
args: Vec<String>, args: Vec<String>,
@ -140,7 +140,7 @@ pub fn log_internal_translated(
} }
} }
pub fn log_internal(kind: PrintType, prefix: &'static str, is_error: bool, message: String) { pub fn log_internal(kind: PrintType, prefix: String, is_error: bool, message: String) {
if let Some(tx) = LOGGER.get() { if let Some(tx) = LOGGER.get() {
tokio::spawn(async move { tokio::spawn(async move {
*UNIQUE.write().await = true; *UNIQUE.write().await = true;
@ -162,12 +162,12 @@ pub fn log_internal(kind: PrintType, prefix: &'static str, is_error: bool, messa
use crate::data::communication::CommunicationValue; use crate::data::communication::CommunicationValue;
use json::JsonValue; use json::JsonValue;
pub fn log_cv_internal(cv: &CommunicationValue, print_type: Option<PrintType>) { pub fn log_cv_internal(prefix: String, cv: &CommunicationValue, print_type: Option<PrintType>) {
let formatted = format_cv(cv); let formatted = format_cv(cv);
log_internal( log_internal(
print_type.unwrap_or(PrintType::General), print_type.unwrap_or(PrintType::General),
"", prefix,
false, false,
formatted, formatted,
); );
@ -211,10 +211,28 @@ pub fn format_cv(cv: &CommunicationValue) -> String {
#[macro_export] #[macro_export]
macro_rules! log_cv { macro_rules! log_cv {
($kind:expr, $cv:expr) => { ($kind:expr, $cv:expr) => {
$crate::util::logger::log_cv_internal(&$cv, Some($kind)) $crate::util::logger::log_cv_internal("".to_string(), &$cv, Some($kind))
}; };
($cv:expr) => { ($cv:expr) => {
$crate::util::logger::log_cv_internal(&$cv, None) $crate::util::logger::log_cv_internal("".to_string(), &$cv, None)
};
}
#[macro_export]
macro_rules! log_cv_in {
($kind:expr, $cv:expr) => {
$crate::util::logger::log_cv_internal("> ".to_string(), &$cv, Some($kind))
};
($cv:expr) => {
$crate::util::logger::log_cv_internal("> ".to_string(), &$cv, None)
};
}
#[macro_export]
macro_rules! log_cv_out {
($kind:expr, $cv:expr) => {
$crate::util::logger::log_cv_internal("< ".to_string(), &$cv, Some($kind))
};
($cv:expr) => {
$crate::util::logger::log_cv_internal("< ".to_string(), &$cv, None)
}; };
} }
@ -223,7 +241,7 @@ macro_rules! log_t {
($key:expr) => { ($key:expr) => {
$crate::util::logger::log_internal_translated( $crate::util::logger::log_internal_translated(
$crate::util::logger::PrintType::General, $crate::util::logger::PrintType::General,
"", "".to_string(),
false, false,
$key, $key,
vec![] vec![]
@ -233,7 +251,7 @@ macro_rules! log_t {
($key:expr, $($arg:expr),+) => { ($key:expr, $($arg:expr),+) => {
$crate::util::logger::log_internal_translated( $crate::util::logger::log_internal_translated(
$crate::util::logger::PrintType::General, $crate::util::logger::PrintType::General,
"", "".to_string(),
false, false,
$key, $key,
vec![$($arg),+] vec![$($arg),+]
@ -245,7 +263,7 @@ macro_rules! log_t_err {
($key:expr) => { ($key:expr) => {
$crate::util::logger::log_internal_translated( $crate::util::logger::log_internal_translated(
$crate::util::logger::PrintType::General, $crate::util::logger::PrintType::General,
">>", "".to_string(),
true, true,
$key, $key,
vec![] vec![]
@ -255,7 +273,7 @@ macro_rules! log_t_err {
($key:expr, $($arg:expr),+) => { ($key:expr, $($arg:expr),+) => {
$crate::util::logger::log_internal_translated( $crate::util::logger::log_internal_translated(
$crate::util::logger::PrintType::General, $crate::util::logger::PrintType::General,
">>", "".to_string(),
true, true,
$key, $key,
vec![$($arg.to_string()),+] vec![$($arg.to_string()),+]
@ -267,7 +285,7 @@ macro_rules! log_t_err {
#[macro_export] #[macro_export]
macro_rules! log { macro_rules! log {
($($arg:tt)*) => { ($($arg:tt)*) => {
$crate::util::logger::log_internal($crate::util::logger::PrintType::General, "", false, format!($($arg)*)) $crate::util::logger::log_internal($crate::util::logger::PrintType::General, "".to_string(), false, format!($($arg)*))
}; };
} }
/// Log an inbound message (`>`). /// Log an inbound message (`>`).
@ -276,7 +294,7 @@ macro_rules! log_in {
($($arg:tt)*) => { ($($arg:tt)*) => {
$crate::util::logger::log_internal( $crate::util::logger::log_internal(
$crate::util::logger::PrintType::General, $crate::util::logger::PrintType::General,
">", ">".to_string(),
false, false,
format!($($arg)*) format!($($arg)*)
) )
@ -288,7 +306,7 @@ macro_rules! log_out {
($($arg:tt)*) => { ($($arg:tt)*) => {
$crate::util::logger::log_internal( $crate::util::logger::log_internal(
$crate::util::logger::PrintType::General, $crate::util::logger::PrintType::General,
"<", "<".to_string(),
false, false,
format!($($arg)*) format!($($arg)*)
) )
@ -300,7 +318,7 @@ macro_rules! log_err {
($($arg:tt)*) => { ($($arg:tt)*) => {
$crate::util::logger::log_internal( $crate::util::logger::log_internal(
$crate::util::logger::PrintType::General, $crate::util::logger::PrintType::General,
">>", ">>".to_string(),
true, true,
format!($($arg)*) format!($($arg)*)
) )