apple-quant-core 0.2.0

Apple Quant's core library.
Documentation
use std::fmt::Write;

use colored::{Color, Colorize};

use smallstr::SmallString;
use smallvec::SmallVec;
use tracing::Level;

use super::{Fields, LogLevelExt};

const CALL_INDENTATION: &str = "     ";
const ARGUMENT_INDENTATION: &str = "        ";

pub(crate) fn short_path(
	file: &str,
	keep_count: usize,
) -> String {
	let parts: SmallVec<[&str; 8]> = file.split(['/', '\\'])
		.filter(|s| !s.is_empty()).collect();

	if parts.len() <= keep_count {
		file.to_string()
	} else {
		format!(
			".../{}",
			parts[parts.len() - keep_count..].join("/")
		)
	}
}

pub(crate) fn now_string() -> SmallString<[u8; 64]> {
	let now_date_time = chrono::Local::now();
	let subsec_nanoseconds = now_date_time.timestamp_subsec_nanos();
	let mut now_string = SmallString::new();

	write!(
		&mut now_string,
		"{}.{:03}_{:03}_{:03}",
		now_date_time.format("%Y-%m-%d %H:%M:%S"),
		subsec_nanoseconds / 1_000_000,
		(subsec_nanoseconds / 1_000) % 1_000,
		subsec_nanoseconds % 1_000
	);

	now_string
}

pub(crate) fn write_fields(
	out: &mut String,
	level: &Level,
	fields: &Fields,
) {
	if fields.is_empty() {
		return;
	}

	let longest_field_name_width = fields.iter().map(|(name, _)| {
		name.chars().count()
	}).max().unwrap_or(0);

	for (
		name,
		value,
	) in fields.iter() {
		let mut lines = value.lines();

		let Some(
			first_line,
		) = lines.next() else {
			continue;
		};

		let _ = writeln!(
			out,
			"{}{ARGUMENT_INDENTATION}{name:<longest_field_name_width$} {} {first_line}",
			"|".color(level.color()),
			"=".color(Color::Blue),
		);

		let hang = " ".repeat(ARGUMENT_INDENTATION.len() + longest_field_name_width + 3);

		for line in lines {
			let _ = writeln!(out, "{}{hang}{line}", "|".color(level.color()));
		}
	}
}

pub(crate) fn write_call(
	out: &mut String,
	level: &Level,
	name: &'static str,
	file: &str,
	line_number: u32,
	fields: Option<&Fields>,
) {
	let mut line: SmallString<[u8; 8]> = SmallString::new();
	let _ = write!(&mut line, "{}", line_number);

	let _ = writeln!(
		out,
		"{}{CALL_INDENTATION}{} {} {}{}{}",
		"|".color(level.color()),
		name.color(Color::White).bold(),
		"at".color(Color::Blue),
		file.color(Color::BrightBlack),
		":".color(Color::BrightBlack),
		line.color(Color::BrightBlack),
	);

	if let Some(
		fields,
	) = &fields {
		write_fields(out, level, fields);
	}
}