rocketsplash-rt 0.2.2

Runtime library for loading and rendering Rocketsplash assets (.rst, .rsf)
Documentation
// <FILE>crates/rocketsplash-rt/src/splash/fnc_load_splash.rs</FILE>
// <DESC>Splash deserialization and validation</DESC>
// <VERS>VERSION: 1.0.1</VERS>
// <WCTX>Runtime library implementation</WCTX>
// <CLOG>Align Splash construction with updated struct fields</CLOG>

use log::debug;
use rocketsplash_formats::{
    CellStyle, Splash as SplashFormat, SPLASH_MIN_SUPPORTED, SPLASH_VERSION,
};

use crate::render::{RenderBuffer, RenderCell};
use crate::splash::Splash;
use crate::{Error, TextStyle};

pub fn load_splash_from_bytes(bytes: &[u8]) -> Result<Splash, Error> {
    let splash: SplashFormat =
        rmp_serde::from_slice(bytes).map_err(|err| Error::InvalidFormat {
            message: err.to_string(),
        })?;
    if splash.version < SPLASH_MIN_SUPPORTED || splash.version > SPLASH_VERSION {
        return Err(Error::UnsupportedVersion {
            format: "splash".to_string(),
            found: splash.version,
            min_supported: SPLASH_MIN_SUPPORTED,
            current: SPLASH_VERSION,
        });
    }
    splash
        .validate()
        .map_err(|message| Error::InvalidFormat { message })?;

    let width = splash.width as usize;
    let height = splash.height as usize;
    let mut buffer = RenderBuffer::new(width, height);
    for (idx, cell) in splash.cells.iter().enumerate() {
        if idx >= buffer.cells.len() {
            break;
        }
        let mut render_cell = RenderCell::empty();
        render_cell.ch = cell.ch;
        render_cell.fg = cell.fg;
        render_cell.bg = cell.bg;
        render_cell.style = to_text_style(cell.style);
        render_cell.opacity = if cell.ch == ' ' { 0 } else { 255 };
        buffer.cells[idx] = render_cell;
    }

    debug!("Loaded splash {} ({}x{})", splash.meta.name, width, height);

    Ok(Splash {
        meta: splash.meta,
        buffer,
    })
}

fn to_text_style(style: CellStyle) -> TextStyle {
    let mut text_style = TextStyle::empty();
    if style.contains(CellStyle::BOLD) {
        text_style |= TextStyle::BOLD;
    }
    if style.contains(CellStyle::ITALIC) {
        text_style |= TextStyle::ITALIC;
    }
    if style.contains(CellStyle::UNDERLINE) {
        text_style |= TextStyle::UNDERLINE;
    }
    if style.contains(CellStyle::REVERSE) {
        text_style |= TextStyle::REVERSE;
    }
    text_style
}

// <FILE>crates/rocketsplash-rt/src/splash/fnc_load_splash.rs</FILE>
// <VERS>END OF VERSION: 1.0.1</VERS>