inkferro-core 0.1.0

Layout, text measurement, ANSI render, and frame-diff engine for inkferro — a Rust-backed, byte-for-byte drop-in for the ink terminal UI library.
Documentation
//! Vendored cli-boxes character table.
//!
//! Source: cli-boxes@4.0.1 (node_modules/cli-boxes/boxes.json in the ink@7 fork).
//! Regenerate by: `cat node_modules/cli-boxes/boxes.json` and transcribing the
//! eight fields (topLeft/top/topRight/right/bottomRight/bottom/bottomLeft/left)
//! for each named style into the constants below.
//!
//! Only the styles that `dom::BorderStyle::Named` can produce are included here.
//! Custom box-drawing characters are handled by `BoxChars::from_custom`.

use std::borrow::Cow;

/// All eight box-drawing characters for one border style.
///
/// Uses `Cow<'static, str>` so named-style constants are zero-copy (`Borrowed`)
/// while `Custom` border styles use `Owned` strings without leaking memory.
#[derive(Debug, Clone)]
pub struct BoxChars {
    pub top_left: Cow<'static, str>,
    pub top: Cow<'static, str>,
    pub top_right: Cow<'static, str>,
    pub right: Cow<'static, str>,
    pub bottom_right: Cow<'static, str>,
    pub bottom: Cow<'static, str>,
    pub bottom_left: Cow<'static, str>,
    pub left: Cow<'static, str>,
}

/// Construct a `BoxChars` from eight `&'static str` literals (named styles).
macro_rules! static_chars {
    ($tl:expr, $t:expr, $tr:expr, $r:expr, $br:expr, $b:expr, $bl:expr, $l:expr) => {
        BoxChars {
            top_left: Cow::Borrowed($tl),
            top: Cow::Borrowed($t),
            top_right: Cow::Borrowed($tr),
            right: Cow::Borrowed($r),
            bottom_right: Cow::Borrowed($br),
            bottom: Cow::Borrowed($b),
            bottom_left: Cow::Borrowed($bl),
            left: Cow::Borrowed($l),
        }
    };
}

/// Owned strings for a `BorderStyle::Custom` box — input to `BoxChars::from_custom`.
///
/// Keeping the fields in a struct avoids the 8-argument clippy lint and makes
/// call sites self-documenting.
pub struct CustomChars {
    pub top_left: String,
    pub top: String,
    pub top_right: String,
    pub right: String,
    pub bottom_right: String,
    pub bottom: String,
    pub bottom_left: String,
    pub left: String,
}

impl BoxChars {
    /// Build from a `CustomChars` (for `BorderStyle::Custom`).
    ///
    /// No leaking: the strings are moved into `Cow::Owned` and freed when the
    /// `BoxChars` value is dropped at the end of each `render_border` call.
    pub fn from_custom(c: CustomChars) -> Self {
        Self {
            top_left: Cow::Owned(c.top_left),
            top: Cow::Owned(c.top),
            top_right: Cow::Owned(c.top_right),
            right: Cow::Owned(c.right),
            bottom_right: Cow::Owned(c.bottom_right),
            bottom: Cow::Owned(c.bottom),
            bottom_left: Cow::Owned(c.bottom_left),
            left: Cow::Owned(c.left),
        }
    }
}

// ─── Named styles from cli-boxes@4.0.1 ───────────────────────────────────────

fn single() -> BoxChars {
    static_chars!("", "", "", "", "", "", "", "")
}
fn double() -> BoxChars {
    static_chars!("", "", "", "", "", "", "", "")
}
fn round() -> BoxChars {
    static_chars!("", "", "", "", "", "", "", "")
}
fn bold() -> BoxChars {
    static_chars!("", "", "", "", "", "", "", "")
}
fn single_double() -> BoxChars {
    static_chars!("", "", "", "", "", "", "", "")
}
fn double_single() -> BoxChars {
    static_chars!("", "", "", "", "", "", "", "")
}
fn classic() -> BoxChars {
    static_chars!("+", "-", "+", "|", "+", "-", "+", "|")
}
fn arrow() -> BoxChars {
    static_chars!("", "", "", "", "", "", "", "")
}

/// Resolve a named style string to `BoxChars`.
///
/// Returns `None` for unknown style names — the caller falls back to a default.
/// Mirrors render-border.ts:32-34:
/// ```ts
/// const box = typeof node.style.borderStyle === 'string'
///   ? cliBoxes[node.style.borderStyle]
///   : node.style.borderStyle;
/// ```
pub fn named(style: &str) -> Option<BoxChars> {
    match style {
        "single" => Some(single()),
        "double" => Some(double()),
        "round" => Some(round()),
        "bold" => Some(bold()),
        "singleDouble" => Some(single_double()),
        "doubleSingle" => Some(double_single()),
        "classic" => Some(classic()),
        "arrow" => Some(arrow()),
        _ => None,
    }
}