~skye/pulver/src/lib.rs

view raw


use chrono::{DateTime, TimeZone};
use clap::Parser;
use lazy_static::lazy_static;
use sbse::fatal;
use toml::Table;

use std::{cmp, fs};

pub mod act;
pub mod db;

pub type Res<T> = Result<T, String>;

macro_rules! toml {
    ($x:expr, $k:expr, $m:ident) => {{
        match $x[$k].$m() {
            Some(x) => x,
            None => fatal!("{} not found in config", $k),
        }
    }};
}

#[derive(Parser, Debug)]
pub struct Args {
    #[arg(short, long)]
    cfg: String,
}

pub struct Cfg {
    pub addr: String,
    pub port: i64,
    pub title: String,
    pub tag: String,
    pub version: String,
    pub css: String,
    pub run: String,
    pub img: String,
}

lazy_static! {
    pub static ref ARGS: Args = Args::parse();
    pub static ref CFG: Cfg = {
        let t = match fs::read_to_string(&ARGS.cfg) {
            Ok(x) => x,
            Err(e) => fatal!("failed to open config: {e}"),
        };

        match t.parse::<Table>() {
            Ok(x) => {
                let r = toml!(x, "run", as_str).to_string();
                Cfg {
                    addr: toml!(x, "addr", as_str).to_string(),
                    port: toml!(x, "port", as_integer),
                    title: toml!(x, "title", as_str).to_string(),
                    version: toml!(x, "version", as_str).to_string(),
                    tag: toml!(x, "tag", as_str).to_string(),
                    css: toml!(x, "css", as_str).to_string(),
                    run: r.as_str().to_string(),
                    img: format!("{r}/img"),
                }
            }
            Err(e) => fatal!("failed to parse config: {e}"),
        }
    };
}

pub mod macros {
    pub use crate::{ex, un};
}

pub fn truncate<T>(x: T, n: usize) -> String
where
    String: From<T>,
{
    let x = String::from(x);
    format!("{}", &x[0..cmp::min(n, x.len())])
}

pub fn fmt_date<T>(x: DateTime<T>) -> String
where
    T: TimeZone,
    <T as TimeZone>::Offset: std::fmt::Display,
{
    x.format("%Y-%m-%d %H:%M").to_string()
}

pub fn fmt_unix(x: i64) -> String {
    fmt_date(match DateTime::from_timestamp(x, 0) {
        Some(x) => x,
        /* uh oh ! */
        None => fatal!("failed to format unix timestamp {x}"),
    })
}

pub fn now_timestamp() -> i64 {
    chrono::Local::now().timestamp()
}

#[macro_export]
macro_rules! ex {
    ($x:expr, $e:pat => $($t:tt)*) => {{
        match $x {
            Ok(x) => Ok(x),
            $e => err_fmt!($($t)*),
        }
    }};
}

#[macro_export]
macro_rules! un {
    ($x:expr, $($t:tt)*) => {{
        match $x {
            Some(x) => Ok(x),
            None => err_fmt!($($t)*),
        }
    }};
}