sfbinpack 0.6.5

Library to read Stockfish Binpacks
Documentation
use js_sys::{Array, Object, Reflect, Uint8Array};
use wasm_bindgen::prelude::*;

use crate::CompressedTrainingDataEntryReader;

fn set_property(target: &Object, key: &str, value: JsValue) -> Result<(), JsValue> {
    Reflect::set(target, &JsValue::from_str(key), &value).map(|_| ())
}

#[wasm_bindgen]
pub fn parse_binpack_chunk(
    bytes: Uint8Array,
    preview_limit: usize,
    skip: usize,
) -> Result<Object, JsValue> {
    let payload = bytes.to_vec();
    let chunk_size = payload.len() as u32;

    let mut file_bytes = Vec::with_capacity(payload.len() + 8);
    file_bytes.extend_from_slice(b"BINP");
    file_bytes.extend_from_slice(&chunk_size.to_le_bytes());
    file_bytes.extend_from_slice(&payload);

    let mut reader = CompressedTrainingDataEntryReader::from_bytes(file_bytes)
        .map_err(|err| JsValue::from_str(&err.to_string()))?;

    let result = Object::new();
    let preview = Array::new();
    let mut entries_read = 0u32;
    let mut offset = 0u32;

    while reader.has_next() {
        let continuation = reader.is_next_entry_continuation();
        let entry = reader.next();

        if offset >= skip as u32 {
            let js_entry = Object::new();

            set_property(
                &js_entry,
                "fen",
                JsValue::from_str(&entry.pos.fen().unwrap()),
            )?;
            set_property(&js_entry, "uci", JsValue::from_str(&entry.mv.as_uci()))?;
            set_property(&js_entry, "score", JsValue::from_f64(entry.score as f64))?;
            set_property(&js_entry, "ply", JsValue::from_f64(entry.ply as f64))?;
            set_property(&js_entry, "result", JsValue::from_f64(entry.result as f64))?;
            set_property(&js_entry, "continuation", JsValue::from_bool(continuation))?;
            set_property(&js_entry, "offset", JsValue::from_f64(offset as f64))?;

            preview.push(&js_entry);

            entries_read += 1;

            if entries_read >= preview_limit as u32 {
                break;
            }
        }

        offset += 1;
    }

    set_property(
        &result,
        "byteLength",
        JsValue::from_f64(payload.len() as f64),
    )?;
    set_property(
        &result,
        "entriesRead",
        JsValue::from_f64(preview.length() as f64),
    )?;
    set_property(&result, "preview", preview.into())?;
    set_property(&result, "totalEntries", JsValue::from_f64(offset as f64))?;

    Ok(result)
}