///|
/// Render a number with two decimals, rounded to nearest hundredth,
/// e.g. `46.3` -> `"46.30"`.
fn fixed_two(x : Float) -> String {
let hundredths = (x * 100.0).round().to_int()
let whole = hundredths / 100
let frac = hundredths % 100
let frac_text = if frac < 10 { "0\{frac}" } else { "\{frac}" }
"\{whole}.\{frac_text}"
}
///|
/// A device's fake memory footprint: `used` and `total`, both in GiB.
/// Only these two numbers are picked by the model; the display text
/// (two-decimal GiB values and usage percentage) is derived from them.
pub struct Memory {
used : Float
total : Float
}
///|
/// Format as fastfetch does, e.g. `46.30 GiB / 128.00 GiB (36%)`.
pub fn Memory::render(self : Memory) -> String {
let percent = (self.used / self.total * 100.0).round().to_int()
"\{fixed_two(self.used)} GiB / \{fixed_two(self.total)} GiB (\{percent}%)"
}
///|
/// A display resolution: `width` and `height` in pixels.
pub struct Resolution {
width : Int
height : Int
}
///|
/// Format as fastfetch does, e.g. `3456x2234`.
pub fn Resolution::render(self : Resolution) -> String {
"\{self.width}x\{self.height}"
}
///|
/// System uptime in whole `hours` and `mins`.
pub struct Uptime {
hours : Int
mins : Int
}
///|
/// Format as fastfetch does, e.g. `3 hours, 12 mins`.
pub fn Uptime::render(self : Uptime) -> String {
"\{self.hours} hours, \{self.mins} mins"
}
///|
/// A CPU: vendor/model `name`, `cores`, and base `clock` in GHz.
pub struct Cpu {
name : String
cores : Int
clock : Float
}
///|
/// Format as fastfetch does, e.g. `Apple M3 Max (16) @ 4.05 GHz`.
pub fn Cpu::render(self : Cpu) -> String {
"\{self.name} (\{self.cores}) @ \{fixed_two(self.clock)} GHz"
}
///|
/// A GPU: vendor/model `name` and discrete VRAM in GB.
/// `vram` is 0 when the GPU has no discrete memory (integrated/Apple silicon).
pub struct Gpu {
name : String
vram : Int
}
///|
/// Format as fastfetch does, e.g. `NVIDIA GeForce RTX 4090 (24GB)`; a GPU
/// without discrete VRAM renders as its bare name.
pub fn Gpu::render(self : Gpu) -> String {
if self.vram > 0 {
"\{self.name} (\{self.vram}GB)"
} else {
self.name
}
}
///|
/// A coherent set of fake hardware/software values for one real device model.
/// Every field is a plausible, internally-consistent value for that product.
pub struct DeviceModel {
name : String
about : String
host : String
os : String
device : String
kernel : String
uptime : Uptime
shell : String
resolution : Resolution
de : String
wm : String
wm_theme : String
terminal : String
term_font : String
cpu : Cpu
gpu : Gpu
memory : Memory
logo : String
}
///|
/// The name of the model used when `--model` is not given.
pub fn default_model_name() -> String {
"m3-max"
}
///|
/// The device profile used when `--model` is not given.
pub fn default_model() -> DeviceModel {
m3_max_model()
}
///|
fn mac_model(
name~ : String,
about~ : String,
host~ : String,
os~ : String,
device~ : String,
kernel~ : String,
resolution~ : Resolution,
cpu~ : Cpu,
gpu~ : Gpu,
memory~ : Memory,
) -> DeviceModel {
{
name,
about,
host,
os,
device,
kernel,
uptime: { hours: 3, mins: 12 },
shell: "zsh 5.9",
resolution,
de: "Quartz Compositor",
wm: "Quartz Compositor",
wm_theme: "Aqua",
terminal: "Apple_Terminal",
term_font: "SF Mono 12",
cpu,
gpu,
memory,
logo: "macos",
}
}
///|
fn linux_model(
name~ : String,
about~ : String,
host~ : String,
os~ : String,
device~ : String,
kernel~ : String,
resolution~ : Resolution,
de~ : String,
wm~ : String,
wm_theme~ : String,
terminal~ : String,
term_font~ : String,
cpu~ : Cpu,
gpu~ : Gpu,
memory~ : Memory,
logo~ : String,
) -> DeviceModel {
{
name,
about,
host,
os,
device,
kernel,
uptime: { hours: 5, mins: 47 },
shell: "zsh 5.9",
resolution,
de,
wm,
wm_theme,
terminal,
term_font,
cpu,
gpu,
memory,
logo,
}
}
///|
fn windows_model(
name~ : String,
about~ : String,
host~ : String,
os~ : String,
device~ : String,
kernel~ : String,
resolution~ : Resolution,
de~ : String,
wm~ : String,
wm_theme~ : String,
terminal~ : String,
term_font~ : String,
cpu~ : Cpu,
gpu~ : Gpu,
memory~ : Memory,
) -> DeviceModel {
{
name,
about,
host,
os,
device,
kernel,
uptime: { hours: 6, mins: 41 },
shell: "powershell 5.1",
resolution,
de,
wm,
wm_theme,
terminal,
term_font,
cpu,
gpu,
memory,
logo: "windows",
}
}
///|
/// MacBook Pro 16" (2023), Apple M3 Max, 128 GB unified memory, 2 TB SSD.
fn m3_max_model() -> DeviceModel {
mac_model(
name="m3-max",
about="macOS MacBook Pro 16\" M3 Max 128 GB / 2 TB",
host="mbp16",
os="macOS 15.5 (Sequoia) 24F74 arm64",
device="MacBook Pro (Mac15,6)",
kernel="Darwin 24.5.0",
resolution={ width: 3456, height: 2234 },
cpu={ name: "Apple M3 Max", cores: 16, clock: 4.05 },
gpu=gpu("Apple M3 Max"),
memory={ used: 46.30, total: 128.00 },
)
}
///|
/// Mac Studio (2025), Apple M3 Ultra, 512 GB unified memory, 4 TB SSD.
fn m3_ultra_model() -> DeviceModel {
mac_model(
name="m3-ultra",
about="macOS Mac Studio M3 Ultra 512 GB / 4 TB",
host="studio",
os="macOS 15.5 (Sequoia) 24F74 arm64",
device="Mac Studio (Mac16,9)",
kernel="Darwin 24.5.0",
resolution={ width: 5120, height: 2880 },
cpu={ name: "Apple M3 Ultra", cores: 32, clock: 4.05 },
gpu=gpu("Apple M3 Ultra"),
memory={ used: 245.76, total: 512.00 },
)
}
///|
/// MacBook Pro 14" (2023), Apple M2 Pro, 32 GB unified memory, 1 TB SSD.
fn m2_pro_model() -> DeviceModel {
mac_model(
name="m2-pro",
about="macOS MacBook Pro 14\" M2 Pro 32 GB / 1 TB",
host="mbp14",
os="macOS 14.6 (Sonoma) 23G80 arm64",
device="MacBook Pro (Mac14,9)",
kernel="Darwin 23.6.0",
resolution={ width: 3024, height: 1964 },
cpu={ name: "Apple M2 Pro", cores: 12, clock: 3.50 },
gpu=gpu("Apple M2 Pro"),
memory={ used: 20.10, total: 32.00 },
)
}
///|
/// MacBook Air (M1, 2020), Apple M1, 8 GB unified memory, 512 GB SSD.
fn m1_air_model() -> DeviceModel {
mac_model(
name="m1-air",
about="macOS MacBook Air (M1) 8 GB / 512 GB",
host="mba",
os="macOS 13.6 (Ventura) 22G120 arm64",
device="MacBook Air (MacBookAir9,1)",
kernel="Darwin 22.6.0",
resolution={ width: 2560, height: 1600 },
cpu={ name: "Apple M1", cores: 8, clock: 3.20 },
gpu=gpu("Apple M1"),
memory={ used: 5.40, total: 8.00 },
)
}
///|
/// ThinkPad X1 Carbon Gen 11, Intel Core i7-1365U, 32 GB RAM, Arch Linux.
fn thinkpad_x1_model() -> DeviceModel {
linux_model(
name="thinkpad-x1",
about="Linux ThinkPad X1 Carbon Gen 11 (Arch)",
host="x1",
os="Arch Linux x86_64",
device="ThinkPad X1 Carbon Gen 11",
kernel="Linux 6.9.3-arch1-1",
resolution={ width: 2880, height: 1800 },
de="GNOME (Wayland)",
wm="Mutter",
wm_theme="Adwaita-dark",
terminal="GNOME Terminal",
term_font="Monospace 11",
cpu={ name: "Intel Core i7-1365U", cores: 10, clock: 5.20 },
gpu=gpu("Intel Iris Xe Graphics"),
memory={ used: 12.30, total: 32.00 },
logo="arch",
)
}
///|
/// Custom desktop: AMD Ryzen 9 7950X, NVIDIA RTX 4090, 64 GB RAM, NixOS.
fn ryzen_desktop_model() -> DeviceModel {
linux_model(
name="ryzen-desktop",
about="Linux desktop Ryzen 9 7950X / RTX 4090 64 GB (NixOS)",
host="helios",
os="NixOS 24.11 (Vicuna) x86_64",
device="MSI MAG B650 TOMAHAWK WIFI",
kernel="Linux 6.9.9-nixos",
resolution={ width: 2560, height: 1440 },
de="KDE Plasma",
wm="KWin",
wm_theme="Breeze Dark",
terminal="kitty",
term_font="Hack Nerd Font 11",
cpu={ name: "AMD Ryzen 9 7950X", cores: 32, clock: 5.70 },
gpu=gpu("NVIDIA GeForce RTX 4090"),
memory={ used: 28.80, total: 64.00 },
logo="nixos",
)
}
///|
/// ASUS ROG Air 16 (2025), Intel Core Ultra 9 285H, RTX 5070, Windows 11.
fn rog_model() -> DeviceModel {
windows_model(
name="rog-air-16",
about="Windows ASUS ROG Air 16 (2025) 32 GB / 1 TB",
host="rog16",
os="Windows 11 Pro 23H2 (22631.3880)",
device="ASUS ROG Air 16 (GA612)",
kernel="Win32 10.0.22631 Build 22631",
resolution={ width: 2560, height: 1600 },
de="Windows Desktop Manager",
wm="DWM",
wm_theme="Dark",
terminal="Windows Terminal",
term_font="Cascadia Mono 12",
cpu={ name: "Intel Core Ultra 9 285H", cores: 16, clock: 5.40 },
gpu=gpu("NVIDIA GeForce RTX 5070 Laptop GPU"),
memory={ used: 12.60, total: 32.00 },
)
}
///|
/// All available device profiles, in the order they are listed in help.
pub fn all_models() -> Array[DeviceModel] {
[
m3_max_model(),
m3_ultra_model(),
m2_pro_model(),
m1_air_model(),
thinkpad_x1_model(),
ryzen_desktop_model(),
rog_model(),
]
}
///|
/// Look up a device profile by its `--model` name.
pub fn model_by_name(name : String) -> DeviceModel? {
all_models().iter().find_first(m => m.name == name)
}
///|
/// The built-in GPU catalog. Discrete GPUs carry a VRAM size in GB; integrated
/// and Apple-silicon GPUs use 0 and render as their bare name.
pub fn all_gpus() -> Array[Gpu] {
[
{ name: "Apple M1", vram: 0 },
{ name: "Apple M2 Pro", vram: 0 },
{ name: "Apple M3 Max", vram: 0 },
{ name: "Apple M3 Ultra", vram: 0 },
{ name: "Intel Iris Xe Graphics", vram: 0 },
{ name: "NVIDIA GeForce RTX 5070 Laptop GPU", vram: 8 },
{ name: "NVIDIA GeForce RTX 4090", vram: 24 },
]
}
///|
/// A GPU by catalog name, defaulting to a bare 0-VRAM entry for unknown names.
fn gpu(name : String) -> Gpu {
all_gpus().iter().find_first(g => g.name == name).unwrap_or({ name, vram: 0 })
}
///|
fn model_about() -> String {
let names = all_models().map(m => m.name).join(", ")
"device model: \{names} (default: \{default_model_name()})"
}