rocketsplash-rt 0.2.2

Runtime library for loading and rendering Rocketsplash assets (.rst, .rsf)
Documentation
// <FILE>crates/rocketsplash-rt/src/render/fnc_to_ansi.rs</FILE>
// <DESC>ANSI output writer for render buffers</DESC>
// <VERS>VERSION: 1.2.0</VERS>
// <WCTX>Runtime library implementation</WCTX>
// <CLOG>Keep ANSI writer focused by extracting transition state helper</CLOG>

use std::io::{self, Write};

use crate::{ColorMode, RenderBuffer};

use super::cls_ansi_state::AnsiState;

pub fn write_ansi<W: Write>(
    buffer: &RenderBuffer,
    color_mode: ColorMode,
    writer: &mut W,
) -> io::Result<()> {
    if color_mode == ColorMode::NoColor {
        write_plain(buffer, writer)?;
        return Ok(());
    }

    let mut state = AnsiState::default();
    for y in 0..buffer.height {
        let row_start = y * buffer.width;
        let row_end = row_start + buffer.width;
        for idx in row_start..row_end {
            let cell = &buffer.cells[idx];
            state.apply(writer, cell, color_mode)?;
            write_char(writer, cell.ch)?;
        }
        if y + 1 < buffer.height {
            writer.write_all(b"\n")?;
        }
    }
    if !state.is_default() {
        writer.write_all(b"\x1b[0m")?;
    }
    Ok(())
}

fn write_plain<W: Write>(buffer: &RenderBuffer, writer: &mut W) -> io::Result<()> {
    for y in 0..buffer.height {
        let row_start = y * buffer.width;
        let row_end = row_start + buffer.width;
        for idx in row_start..row_end {
            let cell = &buffer.cells[idx];
            write_char(writer, cell.ch)?;
        }
        if y + 1 < buffer.height {
            writer.write_all(b"\n")?;
        }
    }
    Ok(())
}

fn write_char<W: Write>(writer: &mut W, ch: char) -> io::Result<()> {
    let mut buffer = [0u8; 4];
    let encoded = ch.encode_utf8(&mut buffer);
    writer.write_all(encoded.as_bytes())
}

// <FILE>crates/rocketsplash-rt/src/render/fnc_to_ansi.rs</FILE>
// <VERS>END OF VERSION: 1.2.0</VERS>