MRH.io logo

MRH.io logo

Adaptive Leadership for Technical Projects

๐ŸŒŒ OrbitDB
P2P databases for the distributed web, build on CRDTs
๐Ÿฆ€ Rust IPFS
A Rust implementation of the Interplanetary File System
๐Ÿ“ˆ TallyLab
A privacy-first, end-to-end encrypted time-series data platform
โš“ Hack for the Sea
An annual hackathon where technology and the ocean meet.
This website does not track you.
The best way to reach out is via e-mail.

Images in rustdoc

Embedding media in cargo-generated Rust docs

May 02, 2020 ๏ฝœ rustdoc, cargo doc, build.rs

According to The Cargo Book, there are several environment variables you can utilize within build scripts. Here, we use:

  • HOST: The target โ€œtripleโ€ of the compilation host
  • CARGO_PKG_NAME: The name of the package
  • TARGET: Target โ€œtripleโ€ being compiled for aka x86_64-unknown-linux-gnu
use std::{ env, fs };
use fs_extra::copy_items;

const COPY_OPTS: fs_extra::dir::CopyOptions = fs_extra::dir::CopyOptions {
    buffer_size: 64000,
    overwrite: true,
    skip_exist: false,
    copy_inside: false,
    depth: 0
};

/// Copies media files (images, etc) of the  ./doc/assets folder into the
/// appropriate ./doc/img subfolder to be included in the docs.rs output.
fn copy_assets_folder() {
    // Should panic if these aren't a thing
    let host = env::var("HOST").unwrap();
    let crate_name = std::env::var("CARGO_PKG_NAME").unwrap();
    let target = std::env::var("TARGET").unwrap();

    // If the target is the same as the host AND no target is
    // _explicitly specified, the directory will be ./target/doc,
    // Elsewhere, the directory will be ./target/{triple}/doc.
    // FIXME: target == host WITH explicitly specified --target
    //
    // Also, Gotta deal with crates that might have a dash in their name
    let sanitized_name = crate_name.replace("-", "_");
    let docs_dir = if host != target {
        format!("./target/{}/doc/{}", target, sanitized_name)
    } else {
        format!("./target/doc/{}", sanitized_name)
    };

    // Pre-emptively create the directory and copy ./doc/img into there
    fs::create_dir_all(&docs_dir).unwrap();
    copy_items(&vec!["./doc/img"], &docs_dir, &COPY_OPTS).unwrap();
}

fn main() {
    println!("cargo:rerun-if-changed=./doc/**");
    copy_assets_folder();
}