// Copyright 2026 Leo Cheng
// SPDX-License-Identifier: Apache-2.0
///|
/// The preset whose pattern is `text`, when `text` is a preset name.
fn preset_of(text : StringView) -> Profile? {
match text {
"serlog" => Some(Profile::Serlog)
"tracing" => Some(Profile::Tracing)
"env_logger" => Some(Profile::EnvLogger)
"python" => Some(Profile::Python)
"logback" | "log4j" => Some(Profile::Logback)
"slog" => Some(Profile::Slog)
"pino" => Some(Profile::Pino)
_ => None
}
}
///|
/// ` key=value` for every field, groups spread as `group.key`; `error` is left
/// out when the pattern shows it in its own hole.
fn write_fields(
out : StringBuilder,
record : Record,
quoted : Bool,
skip_error : Bool,
) -> Unit {
for pair in record.fields {
write_flat(out, pair.0, pair.1, quoted, skip_error)
}
}
///|
fn write_flat(
out : StringBuilder,
key : String,
value : Value,
quoted : Bool,
skip_error : Bool,
) -> Unit {
if skip_error && key == "error" {
return
}
match value {
Map(pairs) =>
for (k, v) in pairs {
write_flat(out, key + "." + k, v, quoted, skip_error)
}
_ => {
out.write_char(' ')
out.write_string(key)
out.write_char('=')
if quoted {
write_logfmt(out, value.to_text())
} else {
out.write_string(value.to_text())
}
}
}
}
///|
/// Shortens the leading segments of a target to their first letter until it
/// fits `width`.
fn shorten(target : StringView, width : Int32) -> String {
if target.char_length() <= width {
return target.to_owned()
}
let sep = if target.contains(("::" : StringView)) { "::" } else { "." }
let parts = target.split(sep)
let out : Array[String] = []
for part in parts {
out.push(part.to_owned())
}
let mut i = 0
while i + 1 < out.length() && joined_length(out, sep) > width {
let chars = out[i].to_array()
out[i] = if chars.length() > 0 { chars[0].to_string() } else { "" }
i = i + 1
}
join(out, sep)
}
///|
fn joined_length(parts : Array[String], sep : String) -> Int32 {
let mut total = 0
for i, part in parts {
if i > 0 {
total = total + sep.length()
}
total = total + part.char_length()
}
total
}
///|
fn join(parts : Array[String], sep : String) -> String {
let out = StringBuilder()
for i, part in parts {
if i > 0 {
out.write_string(sep)
}
out.write_string(part)
}
out.to_string()
}
///|
/// A run of characters as a string.
fn chars_to_string(chars : ArrayView[Char]) -> String {
let out = StringBuilder()
for c in chars {
out.write_char(c)
}
out.to_string()
}
///|
/// The last segment of a path, whichever separator the platform writes.
fn base_name(path : StringView) -> String {
let chars = path.to_array()
let mut start = 0
for i, c in chars {
if c == '/' || c == '\\' {
start = i + 1
}
}
chars_to_string(chars[start:])
}
///|
/// Milliseconds from the identity's start to the record's instant.
fn elapsed_ms(record : Record, identity : Identity) -> Int64 {
if identity.start == 0L {
return 0L
}
floor_div(record.time - identity.start, 1_000_000L)
}