Crate ratatui_ffi

Crate ratatui_ffi 

Source
Expand description

§ratatui_ffi logo ratatui_ffi

CI GitHub Release crates.io crates.io downloads docs.rs

Native C ABI for Ratatui, shipped as a tiny cdylib you can call from C, C#, Python, TypeScript (via FFI), and more. Optimized for hot loops: span‑based setters and batch APIs minimize allocations and marshaling.

§Highlights

  • Widgets: Paragraph, List (+state), Table (+state), Tabs, Gauge, LineGauge, BarChart, Sparkline, Chart, Scrollbar, Clear, RatatuiLogo, Canvas.
  • Layout: layout_split, layout_split_ex (spacing + per‑side margins), layout_split_ex2 (adds Constraint::Ratio).
  • Text/Styles: FfiStyle, FfiSpan, FfiLineSpans; lines of styled spans; paragraph base style, alignment, wrap(trim), scroll; named/RGB/indexed colors; all modifiers (incl. hidden/blink).
  • Blocks: per‑side borders, border type, padding, title alignment, and title as spans across all block‑bearing widgets.
  • Terminal: init/clear, batched frame render, raw/alt toggles, cursor get/set/show, size, event poll and injection.
  • Headless: ASCII snapshots; compact and extended style dumps; structured cell dump (FfiCellInfo).
  • Throughput: list/paragraph/table batching; table multi‑line cells; dataset batching; reserve helpers.
  • Zero‑alloc paths: span‑based label/title/divider setters for hot code paths.

§Quick Start

§Language Bindings

§Building

Build the library:

cargo build --release
# → target/release/libratatui_ffi.so (Linux), .dylib (macOS), ratatui_ffi.dll (Windows)

Use from C (example: Gauge label spans):

FfiStyle white = { .fg = 0x00000010, .bg = 0, .mods = 0 }; // white named
FfiSpan spans[2] = {
  { .text_utf8 = "Load ", .style = white },
  { .text_utf8 = "80%",    .style = white },
};
ratatui_gauge_set_label_spans(gauge, spans, 2);

§Aspects

§Span‑Based Setters (Zero‑Alloc Paths)

Preferred over UTF‑8 string setters in hot loops. All functions treat FfiSpan.text_utf8 as NUL‑terminated UTF‑8 without ownership transfer.

  • Tabs: ratatui_tabs_set_divider_spans(spans, len)
  • Gauge: ratatui_gauge_set_label_spans(spans, len), ratatui_gauge_set_block_title_spans(spans, len, show_border)
  • LineGauge: ratatui_linegauge_set_label_spans(spans, len)
  • BarChart: ratatui_barchart_set_labels_spans(lines, len), ratatui_barchart_set_block_title_spans(spans, len, show_border)
  • Table: ratatui_table_set_block_title_spans(spans, len, show_border)
  • Paragraph/List/Tabs/LineGauge/Chart/Sparkline/Scrollbar/Canvas: *_set_block_title_spans(spans, len, show_border)

Notes and limits:

  • Tabs divider: if a single span is provided, style is preserved; otherwise texts are concatenated (ratatui accepts a single Span).
  • Gauge label: texts are concatenated; use ratatui_gauge_set_styles(..., label_style, ...) for label styling.
  • BarChart labels: per‑label styling is not supported by ratatui; text‑only, same as TSV path.

§FFI Types

  • FfiStyle { fg: u32, bg: u32, mods: u16 } with helpers ratatui_color_rgb, ratatui_color_indexed.
  • FfiSpan { text_utf8: *const c_char, style: FfiStyle }
  • FfiLineSpans { spans: *const FfiSpan, len: usize }
  • Structured outputs: FfiCellInfo (headless), list/table state types, draw commands for batched frames.

§Headless Rendering

  • Text snapshots: ratatui_headless_render_frame, and per‑widget helpers (_paragraph, _list, _table, …).
  • Style snapshots:
    • Compact: ratatui_headless_render_frame_styles → rows of FG2 BG2 MOD4 hex (named palette).
    • Extended: ratatui_headless_render_frame_styles_exFG8 BG8 MOD4 hex (FfiStyle encoding).
    • Structured cells: ratatui_headless_render_frame_cells → fill array of FfiCellInfo.

§Feature Bits (Introspection)

Call ratatui_ffi_feature_bits() to detect support at runtime. Bits include:

  • SCROLLBAR, CANVAS, STYLE_DUMP_EX, BATCH_TABLE_ROWS, BATCH_LIST_ITEMS, COLOR_HELPERS, AXIS_LABELS, SPAN_SETTERS.

§Tips

§Hot‑Path Tips

  • Prefer span‑based setters and batched APIs to avoid allocations and repeated marshaling.
  • Reserve capacity where possible (ratatui_*_reserve_*) before large appends.
  • Use headless render snapshots in CI for fast, deterministic tests.

§Runtime Behavior & Logging

  • By default raw mode is enabled; use RATATUI_FFI_NO_RAW=1 to disable; RATATUI_FFI_ALTSCR=1 to use the alternate screen.
  • Set RATATUI_FFI_TRACE=1 to trace ENTER/EXIT of FFI calls (stderr and optional file).
  • Set RATATUI_FFI_LOG=<path> to write logs; truncate per run; use RATATUI_FFI_LOG_APPEND=1 to append.
  • Functions that interact with the terminal are wrapped in panic guards and validate pointers/rects.

§Development

§Introspection & Codegen

The ffi_introspect tool drives coverage and optional code generation directly from the target crate sources (no rustdoc scraping). It is generic and configured via Cargo.toml.

  • One‑shot run (reads Cargo.toml metadata, no args):

    • cargo run --quiet --bin ffi_introspect
    • Clones the configured repo/tag into target/src-cache/<repo>/<tag> (cached), generates code if configured, or prints a clean, hierarchical coverage log (one line per symbol).
    • Build first to see green binary coverage: cargo build --release (or debug).
  • Configure in Cargo.toml:

    • Under [package.metadata.ffi_introspect] set:
      • emit_rs → output file for generated symbols/palettes (e.g., src/ffi/generated.rs).
      • widgets_emit_rs → optional output for widget DTOs (experimental).
      • git_url, git_tag (optional), dep_name (to derive tag from Cargo.lock).
      • const_root (path prefix for consts) and fn_prefix (name prefix for getters).
      • symbol_namespaces and set_modules to control which modules emit string getters and Set structs.
      • const_modules to scan nested modules (e.g., symbols::half_block) for char/u16 constants.
      • dto_enum_u32 to map specific enums to u32 in generated DTOs (e.g., Alignment, BorderType).
      • dto_renames to rename generated DTOs (e.g., layout::Rect=FfiRect).
      • macros.* to override macro names so the generator can integrate with any project.
  • What gets generated:

    • Public &'static str constants in configured namespaces → extern getters.
    • struct Set constants (module‑scoped, all &str fields) → repr(C) FFI struct + getter per const.
    • Palette structs (all Color fields) → repr(C) u32 palette FFI struct + getters; single Color consts → u32 getters.
    • Char/u16 symbols within configured const_modules (e.g., half-block characters, braille BLANK).
    • Widgets DTOs: placeholder file if widgets_emit_rs is configured (implementation evolving).
  • Using the output:

    • The library includes include!("ffi/generated.rs") so getters are compiled into the cdylib.
    • Commit generated files so consumers don’t need the tool at runtime.

§Safety Checks (optional)

For QA and development, you can compile additional input‑validation guards into the FFI layer.

  • Feature: ffi_safety (disabled by default)

    • Build with: cargo build --features ffi_safety
    • Adds lightweight validation at FFI boundaries and a small control API.
    • Default builds remain zero‑overhead — no checks or safety symbols are compiled.
  • Runtime control (only available when built with ffi_safety):

    • void ratatui_ffi_set_safety(bool enabled) — enable/disable checks at runtime.
    • void ratatui_ffi_set_caps(u16 max_w, u16 max_h, u32 max_area, u32 max_text_len, u32 max_batch) — tune caps.
    • FfiStr ratatui_ffi_last_error() / void ratatui_ffi_clear_last_error() — observe/clear the last safety error.
  • What is validated today

    • Draw rectangles: dimension and viewport sanity in renderer and per‑widget draw_in paths.
    • Lists: per‑item UTF‑8 length cap; batch length cap; selected/offset clamped to item count.
    • Paragraphs: per‑item UTF‑8 length cap; batch length cap; rect sanity in draw_in.
    • Tables: rect sanity in both stateful and stateless draw_in.
  • Recommended usage for bindings

    • Ship two artifacts if you prefer (with/without ffi_safety), or ask advanced users to build from submodule.
    • In debug/QA builds of the ffi_safety artifact, call ratatui_ffi_set_safety(true) at startup and optionally set caps. In release, leave safety disabled.

§C Header Generation

This crate exposes a C ABI and ships a cbindgen config to generate a header for C/C++ consumers.

Generate include/ratatui_ffi.h with either:

# Rusty way (requires cbindgen installed):
cargo run --quiet --bin gen_header

# or Bash helper:
bash tools/gen_header.sh

Then include it from C/C++ bindings. CI can generate and attach it to releases.

§CI Notes

Release builds can produce prebuilt binaries for Linux/macOS/Windows. See the GitHub Actions in this repo and the C# binding repo for multi‑RID examples.

Macros§

ratatui_block_adv_fn
ratatui_block_title_alignment_fn
ratatui_block_title_fn
ratatui_block_title_spans_fn
ratatui_const_char_getter
ratatui_const_color_u32_getter
ratatui_const_palette_u32_getter
ratatui_const_str_getter
ratatui_const_struct_getter
ratatui_const_u16_getter
ratatui_define_ffi_str_struct
ratatui_define_ffi_u32_struct
ratatui_reserve_vec_fn
ratatui_set_selected_i32_fn
ratatui_set_style_fn

Structs§

FfiAccentedPaletteU32
FfiBorders
FfiCellInfo
FfiCellLines
FfiDrawCmd
FfiEvent
FfiFeatures
FfiKeyEvent
FfiKeyMods
FfiLineSpans
FfiList
FfiListState
FfiMarginDto
FfiNonAccentedPaletteU32
FfiOffsetDto
FfiPositionDto
FfiRect
FfiRowCellsLines
FfiSizeDto
FfiSpan
FfiStr
FfiStyle
FfiStyleMods
FfiSymbolsBarSet
FfiSymbolsBlockSet
FfiSymbolsBorderSet
FfiSymbolsLineSet
FfiSymbolsScrollbarSet
FfiTable
FfiTableState
FfiTabs
FfiTabsStyles
FfiTailwindPaletteU32
FfiTerminal
FfiU16Slice

Enums§

FfiAlign
FfiBorderType
FfiClearType
FfiColor
FfiConstraint
FfiDirection
FfiEventKind
FfiFlex
FfiGraphType
FfiHighlightSpacing
FfiKeyCode
FfiLegendPosition
FfiListDirection
FfiMapResolution
FfiMarker
FfiMouseButton
FfiMouseKind
FfiPosition
FfiRenderDirection
FfiSize
FfiSpacing
FfiViewport
FfiWidgetKind

Functions§

apply_block_title_alignment
borders_from_bits
build_block_from_adv
color_from_u32
color_to_u32
ratatui_bar_get_nine_levels
ratatui_bar_get_three_levels
ratatui_block_get_nine_levels
ratatui_block_get_three_levels
ratatui_border_get_double
ratatui_border_get_empty
ratatui_border_get_full
ratatui_border_get_one_eighth_bottom_eight
ratatui_border_get_one_eighth_left_eight
ratatui_border_get_one_eighth_right_eight
ratatui_border_get_one_eighth_tall
ratatui_border_get_one_eighth_top_eight
ratatui_border_get_one_eighth_wide
ratatui_border_get_plain
ratatui_border_get_proportional_tall
ratatui_border_get_proportional_wide
ratatui_border_get_quadrant_block
ratatui_border_get_quadrant_bottom_half
ratatui_border_get_quadrant_bottom_left
ratatui_border_get_quadrant_bottom_right
ratatui_border_get_quadrant_inside
ratatui_border_get_quadrant_left_half
ratatui_border_get_quadrant_outside
ratatui_border_get_quadrant_right_half
ratatui_border_get_quadrant_top_half
ratatui_border_get_quadrant_top_left
ratatui_border_get_quadrant_top_left_bottom_left_bottom_right
ratatui_border_get_quadrant_top_left_bottom_right
ratatui_border_get_quadrant_top_left_top_right_bottom_left
ratatui_border_get_quadrant_top_left_top_right_bottom_right
ratatui_border_get_quadrant_top_right
ratatui_border_get_quadrant_top_right_bottom_left
ratatui_border_get_quadrant_top_right_bottom_left_bottom_right
ratatui_border_get_rounded
ratatui_border_get_thick
ratatui_braille_get_blank
ratatui_color_indexed
ratatui_color_rgb
ratatui_ffi_feature_bits
ratatui_ffi_version
ratatui_half_block_get_full
ratatui_half_block_get_lower
ratatui_half_block_get_upper
ratatui_inject_resize
ratatui_line_get_bottom_left
ratatui_line_get_bottom_right
ratatui_line_get_cross
ratatui_line_get_double
ratatui_line_get_double_bottom_left
ratatui_line_get_double_bottom_right
ratatui_line_get_double_cross
ratatui_line_get_double_horizontal
ratatui_line_get_double_horizontal_down
ratatui_line_get_double_horizontal_up
ratatui_line_get_double_top_left
ratatui_line_get_double_top_right
ratatui_line_get_double_vertical
ratatui_line_get_double_vertical_left
ratatui_line_get_double_vertical_right
ratatui_line_get_horizontal
ratatui_line_get_horizontal_down
ratatui_line_get_horizontal_up
ratatui_line_get_normal
ratatui_line_get_rounded
ratatui_line_get_rounded_bottom_left
ratatui_line_get_rounded_bottom_right
ratatui_line_get_rounded_top_left
ratatui_line_get_rounded_top_right
ratatui_line_get_thick
ratatui_line_get_thick_bottom_left
ratatui_line_get_thick_bottom_right
ratatui_line_get_thick_cross
ratatui_line_get_thick_horizontal
ratatui_line_get_thick_horizontal_down
ratatui_line_get_thick_horizontal_up
ratatui_line_get_thick_top_left
ratatui_line_get_thick_top_right
ratatui_line_get_thick_vertical
ratatui_line_get_thick_vertical_left
ratatui_line_get_thick_vertical_right
ratatui_line_get_top_left
ratatui_line_get_top_right
ratatui_line_get_vertical
ratatui_line_get_vertical_left
ratatui_line_get_vertical_right
ratatui_palette_material_get_amber
ratatui_palette_material_get_black
ratatui_palette_material_get_blue
ratatui_palette_material_get_blue_gray
ratatui_palette_material_get_brown
ratatui_palette_material_get_cyan
ratatui_palette_material_get_deep_orange
ratatui_palette_material_get_deep_purple
ratatui_palette_material_get_gray
ratatui_palette_material_get_green
ratatui_palette_material_get_indigo
ratatui_palette_material_get_light_blue
ratatui_palette_material_get_light_green
ratatui_palette_material_get_lime
ratatui_palette_material_get_orange
ratatui_palette_material_get_pink
ratatui_palette_material_get_purple
ratatui_palette_material_get_red
ratatui_palette_material_get_teal
ratatui_palette_material_get_white
ratatui_palette_material_get_yellow
ratatui_palette_tailwind_get_amber
ratatui_palette_tailwind_get_black
ratatui_palette_tailwind_get_blue
ratatui_palette_tailwind_get_cyan
ratatui_palette_tailwind_get_emerald
ratatui_palette_tailwind_get_fuchsia
ratatui_palette_tailwind_get_gray
ratatui_palette_tailwind_get_green
ratatui_palette_tailwind_get_indigo
ratatui_palette_tailwind_get_lime
ratatui_palette_tailwind_get_neutral
ratatui_palette_tailwind_get_orange
ratatui_palette_tailwind_get_pink
ratatui_palette_tailwind_get_purple
ratatui_palette_tailwind_get_red
ratatui_palette_tailwind_get_rose
ratatui_palette_tailwind_get_sky
ratatui_palette_tailwind_get_slate
ratatui_palette_tailwind_get_stone
ratatui_palette_tailwind_get_teal
ratatui_palette_tailwind_get_violet
ratatui_palette_tailwind_get_white
ratatui_palette_tailwind_get_yellow
ratatui_palette_tailwind_get_zinc
ratatui_scrollbar_get_double_horizontal
ratatui_scrollbar_get_double_vertical
ratatui_scrollbar_get_horizontal
ratatui_scrollbar_get_vertical
ratatui_string_free
ratatui_symbols_get_braille_dots_flat
ratatui_terminal_draw_frame
spans_from_ffi
style_from_ffi