#![deny(unconditional_recursion)]
#![no_std]

use core::fmt;


pub mod ram_disk;
pub mod replay_disk;


extern crate alloc;



/// Implements Display to print the number with metric prefixes
/// using fixed 4 space plus the metric prefix (you have to print a unit thereafter)
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct MetricNumber(pub usize);
impl fmt::Display for MetricNumber {
	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
		let suffixes = [" ", "K", "M", "G", "T", "P", "E", "Z", "Y", "R", "Q"];

		let n = self.0;

		let i = (n.checked_ilog10().unwrap_or(0) as usize / 3).min(suffixes.len());

		let div = 10_usize.pow(i as u32 * 3);
		let full = n / div;
		let frac = (1000 * (n % div)) / div;

		if full >= 100 || i == 0 {
			write!(f, "{:4}{}", full, suffixes[i])
		} else if full >= 10 {
			write!(f, "{:2}.{:01}{}", full, frac / 100, suffixes[i])
		} else {
			write!(f, "{:1}.{:02}{}", full, frac / 10, suffixes[i])
		}
	}
}

/// Implements Display to print the number with IEC-prefixes
/// using fixed 4 space plus the prefix (you have to print a unit thereafter).
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct IecNumber(pub usize);
impl fmt::Display for IecNumber {
	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
		let suffixes = [
			"  ", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", "Ri", "Qi",
		];

		let n = self.0;

		let i = (n.checked_ilog2().unwrap_or(0) as usize / 10).min(suffixes.len());

		let div = 2_usize.pow(i as u32 * 10);
		let full = n / div;
		let frac = (1000 * (n % div)) / div;

		if full >= 100 || i == 0 {
			write!(f, "{:4}{}", full, suffixes[i])
		} else if full >= 10 {
			write!(f, "{:2}.{:01}{}", full, frac / 100, suffixes[i])
		} else {
			write!(f, "{:1}.{:02}{}", full, frac / 10, suffixes[i])
		}
	}
}
