ascii-linker

Crates.ioascii-linker
lib.rsascii-linker
version1.0.0
created_at2025-12-02 00:42:05.51872+00
updated_at2025-12-02 00:42:05.51872+00
descriptionA procedural macro library to embed a .bapple file into a Rust binary.
homepagehttps://github.com/S0raWasTaken/bad_apple
repositoryhttps://github.com/S0raWasTaken/bad_apple
max_upload_size
id1960923
size27,612
S0ra (S0raWasTaken)

documentation

https://docs.rs/ascii-linker

README

ascii_linker

Embed ASCII art animations generated by asciic directly into your Rust binary at compile time.

Overview

This crate provides two procedural macros for working with .bapple files:

  • link_frames! - Embeds decompressed ASCII frames as strings (zero runtime overhead)
  • embed_full! - Embeds compressed frames with audio data and timing metadata (smaller binaries)

Usage

Simple Animation (link_frames!)

use ascii_linker::link_frames;

const FRAMES: &[&str] = link_frames!("./animation.bapple");

fn main() {
    for frame in FRAMES {
        print!("\x1B[2J\x1B[H{}", frame);
        std::thread::sleep(std::time::Duration::from_millis(33));
    }
}

Full Animation with Audio (embed_full!)

Add zstd to your dependencies:

[dependencies]
ascii_linker = "..."
zstd = "0.13"
use ascii_linker::embed_full;

const BAPPLE: (&[&[u8]], &[u8], u64) = embed_full!("./animation.bapple");

fn main() {
    let (frames, _audio, frametime_us) = BAPPLE;

    let mut lock = std::io::stdout().lock();
    
    for compressed_frame in frames {
        let frame = zstd::decode_all(&compressed_frame[..]).unwrap();

        lock.write_all(b"\x1b[2J\r\x1b[H").unwrap();
        lock.write_all(&frame).unwrap();
        lock.flush().unwrap();
        
        std::thread::sleep(std::time::Duration::from_micros(frametime_us));
    }
}

What's a .bapple?

A tar archive containing:

  • Zstd-compressed ASCII art frames
  • Audio data (optional)
  • Timing metadata in RON format

These files are automatically generated by asciic.

Why?

link_frames! benefits:

  • Zero runtime overhead - All frames decompressed at compile time
  • Instant frame access - No decompression needed
  • Single binary distribution - No external files required
  • No file I/O needed - Perfect for embedded systems
  • Works in bare-metal environments - Kernels, bootloaders, etc.

embed_full! benefits:

  • Smaller binary size - Frames stay compressed
  • Includes audio - Audio data embedded alongside frames
  • Timing metadata - Automatic framerate/timing information
  • More flexible - Control decompression at runtime

Trade-offs

Feature link_frames! embed_full!
Binary size Large (decompressed) Small (compressed)
Runtime overhead None Decompression per frame
Dependencies None Requires zstd
Audio support No Yes
Timing metadata No Yes
Best for Small animations, embedded systems Larger animations, desktop apps

License

MIT

Commit count: 0

cargo fmt