marmalade 0.0.1

A simple UI library for video games
Documentation
use base64::{engine::general_purpose, Engine};
use futures_channel::mpsc;
use futures_util::StreamExt;
use wasm_bindgen::prelude::Closure;
use wasm_bindgen::JsCast;
use web_sys::HtmlImageElement;

pub async fn load(src: &str) -> Result<HtmlImageElement, ()> {
    let img = HtmlImageElement::new().unwrap();

    let (mut send, mut recv) = mpsc::channel(0);

    let mut send_clone = send.clone();

    let load_closure = Closure::once(move || {
        send_clone.try_send(true).unwrap();
    });
    img.set_onload(Some(load_closure.as_ref().unchecked_ref()));

    let err_closure = Closure::once(move || {
        send.try_send(false).unwrap();
    });
    img.set_onerror(Some(err_closure.as_ref().unchecked_ref()));

    img.set_src(src);

    if recv.next().await.unwrap() {
        Ok(img)
    } else {
        Err(())
    }
}

pub enum Format {
    Apng,
    Avif,
    Gif,
    Jpeg,
    Png,
    Svg,
    WebP,
}

impl Format {
    #[must_use]
    pub const fn get_mime(&self) -> &str {
        match self {
            Self::Apng => "image/apng",
            Self::Avif => "image/avif",
            Self::Gif => "image/gif",
            Self::Jpeg => "image/jpeg",
            Self::Png => "image/png",
            Self::Svg => "image/svg+xml",
            Self::WebP => "image/webp",
        }
    }
}

pub async fn from_bytes(bytes: &[u8], format: &Format) -> Result<HtmlImageElement, ()> {
    let mut img = format!("data:{};base64,", format.get_mime());

    general_purpose::STANDARD.encode_string(bytes, &mut img);

    load(&img).await
}