/* * common functions and utilities */ use colored::Colorize; use rand::{distributions::Alphanumeric, thread_rng, Rng}; use crate::{macros::*, now, CFG}; use std::{ fmt::Display, io::{self, Write}, }; pub mod cfg { pub const VERSION: &str = "version 0.0.1: OXIDIZED"; } pub mod err { pub const IO_ERR: i32 = 1; pub const DB_CON_ERR: i32 = 2; } pub fn page(t: X, b: Y) -> String where String: From, String: From, { let t = String::from(t); let b = String::from(b); log!("page: t: {t:?}"); format!( r#" {title} :: {t}
{b}
"#, title = match CFG["title"].as_str() { Some(x) => x, None => "badboy git", }, version = cfg::VERSION ) } pub fn err(m: &str, goto: &str) -> String { page( format!("error :: {m}").as_str(), format!( r#"

{m}

go back

"# ), ) } pub fn mkhash() -> String { thread_rng() .sample_iter(&Alphanumeric) .take(32) .map(char::from) .collect() } pub fn puts(s: T) where String: From, T: Display, { print!("{s}"); match io::stdout().flush() { Ok(_) => (), Err(e) => eprintln!("error flushing stdout: {e}"), }; } /** panic except not really because we don't want to kill the server * for now just log */ pub fn panic(e: T) -> ! where String: From, T: Display, { eprintln!("{}: {e}", "fatal error".bold().red()); std::process::exit(-1); } /** basename of a path */ pub fn basename(s: &str) -> &str { let x: Vec<&str> = s.split("/").collect(); if x.len() > 0 { x[x.len() - 1] } else { "" } } /** dirname of a path */ pub fn dirname(s: &str) -> String { let mut x: Vec<&str> = s.split("/").collect(); /* remove the last item, which is the basename */ x.pop(); if x.len() > 0 { x.join("/") } else { String::new() } } /** generic trim for trim_right and trim_left, taking an argument that determines * if the chars are reversed. * setting rev to true makes it a trim left, otherwise it's a trim right */ fn trim_(s: T, c: char, rev: bool) -> String where String: From, { let mut s = { let s = String::from(s); /* reverse if needed */ if rev { s.chars().rev().collect::() } else { s } }; /* mutable iterator */ let mut i = s.chars().rev().collect::>(); let mut i = i.iter_mut(); /* pop while char == c */ while let Some(x) = i.next() { if *x == c { let p = s.pop(); safe_assert_eq!(p, Some(c)); } else { break; } } if rev { s.chars().rev().collect::() } else { s } } /** trim all chars matching c from the left */ pub fn trim_left(s: T, c: char) -> String where String: From, { trim_(s, c, true) } /** trim all chars matching c from the right */ pub fn trim_right(s: T, c: char) -> String where String: From, { trim_(s, c, false) } /** * turn a raw string into a "heredoc" by stripping the whitespace on * the beginning of each line */ /* pub fn heredoc(x: X) -> String where String: From, { let x = String::from(x); x.split("\n").map(|x| trim_left(x, ' ')).collect::() } */ /** convert an int to a corresponding bool */ pub fn i64_to_bool(x: i64) -> bool { if x == 0 { false } else { true } } /** convert a bool to a corresponding int */ pub fn bool_to_i64(x: bool) -> i64 { if x { 1 } else { 0 } }