Something went wrong. Try again.
A charm-like tui library
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100//! Sequence parameter parsing for the input decoder.//!//! Port of the pieces of `github.com/charmbracelet/x/ansi/parser` and//! `github.com/charmbracelet/x/ansi` (v0.11.8) that the ultraviolet//! `EventDecoder` consumes: packed sequence parameters, and the `Cmd`/`Param`//! packing model. Parameters with sub-parameters (colon-separated) are packed//! with a `HasMore` flag exactly as the Go `Parameter` helper does.
const std = @import("std");
/// Shift amounts and masks for packed sequence parameters / commands.pub const prefix_shift: u32 = 8;pub const intermed_shift: u32 = 16;pub const final_mask: i32 = 0xff;pub const has_more_flag: i32 = std.math.minInt(i32);pub const param_mask: i32 = ~has_more_flag;pub const missing_param: i32 = param_mask;pub const max_param: i32 = std.math.maxInt(u16);
/// The maximum number of parameters a sequence can hold.pub const max_params_size: usize = 32;
/// A raw packed parameter. Mirrors `ansi.Param` (a Go `int`)./// The sign bit carries the `HasMoreFlag`; the value uses `param_mask`.pub const Param = i32;
/// Whether the parameter has following sub-parameters.pub inline fn paramHasMore(s: Param) bool { return s & has_more_flag != 0;}
/// Unpacks the parameter value, falling back to `def` when missing.pub inline fn paramValue(s: Param, def: i32) i32 { const p = s & param_mask; if (p == missing_param) return def; return p;}
/// Packs a parameter value plus whether it has following sub-parameters.pub inline fn packParam(p: i32, hasMore: bool) Param { var s = p & param_mask; if (hasMore) s |= has_more_flag; return s;}
/// A packed CSI/DCS sequence command. Mirrors `ansi.Cmd`.pub const Cmd = struct { value: i32,
pub fn prefix(c: Cmd) u8 { return @as(u8, @intCast((c.value >> prefix_shift) & final_mask)); }
pub fn intermediate(c: Cmd) u8 { return @as(u8, @intCast((c.value >> intermed_shift) & final_mask)); }
pub fn final(c: Cmd) u8 { return @as(u8, @intCast(c.value & final_mask)); }
pub fn applyPrefix(c: Cmd, b: u8) Cmd { return .{ .value = c.value | (@as(i32, b) << prefix_shift) }; }
pub fn applyIntermed(c: Cmd, b: u8) Cmd { return .{ .value = c.value | (@as(i32, b) << intermed_shift) }; }
pub fn applyFinal(c: Cmd, b: u8) Cmd { return .{ .value = c.value | b }; }};
/// A packed list of sequence parameters. Mirrors `ansi.Params`.pub const Params = struct { items: []Param,
pub fn len(p: Params) usize { return p.items.len; }
/// Returns `(value, hasMore, ok)` for the parameter at index `i`. /// Falls back to `def` when missing or out of bounds (ok = false on OOB). pub fn at(p: Params, i: usize, def: i32) struct { value: i32, has_more: bool, ok: bool } { if (i >= p.items.len) return .{ .value = def, .has_more = false, .ok = false }; return .{ .value = paramValue(p.items[i], def), .has_more = paramHasMore(p.items[i]), .ok = true, }; }
/// `HasMore` for the parameter at index `i` (false when out of bounds). pub fn hasMore(p: Params, i: usize) bool { if (i >= p.items.len) return false; return paramHasMore(p.items[i]); }};