Create the fuga package

This commit is contained in:
Jesse Braham 2024-12-08 13:01:58 +01:00
parent 4cdbccbc8a
commit ee08ffb28d
6 changed files with 121 additions and 1 deletions

View File

@ -1,6 +1,6 @@
[workspace]
resolver = "2"
members = ["onihime"]
members = ["onihime", "tools/*"]
[workspace.package]
authors = ["Jesse Braham <jesse@beta7.io>"]

16
tools/fuga/Cargo.toml Normal file
View File

@ -0,0 +1,16 @@
[package]
name = "fuga"
version = "0.0.0"
authors.workspace = true
edition.workspace = true
homepage.workspace = true
repository.workspace = true
license.workspace = true
[[bin]]
name = "fuga"
path = "src/bin/fuga.rs"
[dependencies]
clap = { version = "4.5.21", features = ["derive", "wrap_help"] }
log = { version = "0.4.22", features = ["std"] }

View File

@ -0,0 +1,30 @@
use clap::{
builder::{styling::Style, Styles},
Parser,
Subcommand,
};
use fuga::{color, command, AppResult};
const HEADER_STYLE: Style = Style::new().fg_color(Some(color::RED)).bold().underline();
const LITERAL_STYLE: Style = Style::new().fg_color(Some(color::PURPLE)).bold();
const STYLES: Styles = Styles::styled()
.usage(HEADER_STYLE)
.header(HEADER_STYLE)
.literal(LITERAL_STYLE);
#[derive(Debug, Parser)]
#[command(styles = STYLES, version)]
struct Cli {
#[command(subcommand)]
command: Command,
}
#[derive(Debug, Subcommand)]
enum Command {}
fn main() -> AppResult<()> {
fuga::logger::init()?;
match Cli::parse().command {}
}

21
tools/fuga/src/color.rs Normal file
View File

@ -0,0 +1,21 @@
pub use clap::builder::styling::Reset;
use clap::builder::styling::{Color, RgbColor};
pub const RED: Color = Color::Rgb(RgbColor(225, 55, 55)); // Red
pub const ORANGE: Color = Color::Rgb(RgbColor(215, 140, 100)); // Orange
pub const WHITE: Color = Color::Rgb(RgbColor(255, 255, 255)); // White
pub const BLUE: Color = Color::Rgb(RgbColor(60, 140, 185)); // Blue
pub const PURPLE: Color = Color::Rgb(RgbColor(180, 130, 215)); // Purple
pub trait EscapeSequence {
fn to_escape_sequence(&self) -> String;
}
impl EscapeSequence for Color {
fn to_escape_sequence(&self) -> String {
match self {
Color::Rgb(RgbColor(r, g, b)) => format!("\x1b[1;38;2;{r};{g};{b}m"),
_ => unimplemented!(),
}
}
}

6
tools/fuga/src/lib.rs Normal file
View File

@ -0,0 +1,6 @@
#![deny(rust_2018_idioms, unsafe_code)]
pub mod color;
pub mod logger;
pub type AppResult<T> = std::result::Result<T, Box<dyn std::error::Error>>;

47
tools/fuga/src/logger.rs Normal file
View File

@ -0,0 +1,47 @@
use std::str::FromStr as _;
use crate::color::{self, EscapeSequence as _};
struct FugaLogger {
level: log::LevelFilter,
}
impl log::Log for FugaLogger {
fn enabled(&self, metadata: &log::Metadata<'_>) -> bool {
metadata.level() <= self.level
}
fn log(&self, record: &log::Record<'_>) {
if self.enabled(record.metadata()) {
let style = match record.level() {
log::Level::Error => color::RED.to_escape_sequence(),
log::Level::Warn => color::ORANGE.to_escape_sequence(),
log::Level::Info => color::WHITE.to_escape_sequence(),
log::Level::Debug => color::BLUE.to_escape_sequence(),
log::Level::Trace => color::PURPLE.to_escape_sequence(),
};
eprintln!(
"{style}{: <5}{} {}",
record.level(),
color::Reset.render(),
record.args()
);
}
}
fn flush(&self) {}
}
pub fn init() -> Result<(), log::SetLoggerError> {
let level = if let Some(level) = std::option_env!("FUGA_LOG") {
log::LevelFilter::from_str(level).unwrap_or(log::LevelFilter::Off)
} else {
log::LevelFilter::Info
};
let logger = FugaLogger { level };
log::set_boxed_logger(Box::new(logger)).map(|()| log::set_max_level(level))?;
Ok(())
}