hardy-sqlite-storage 0.5.0

SQLite metadata storage backend for Hardy BPA
Documentation
use base64::prelude::*;
use sha1::Digest;
use std::io::{Read, Write};

fn main() {
    gen_migrations("schemas/").expect("Failed to build migration info");
}

fn gen_migrations(src_dir: &str) -> Result<(), Box<dyn std::error::Error>> {
    println!("cargo:rerun-if-changed={src_dir}");

    let out_dir = std::env::var("OUT_DIR")?;
    let mut out = std::io::BufWriter::new(std::fs::File::create(
        [&out_dir, "migrations.rs"]
            .iter()
            .collect::<std::path::PathBuf>(),
    )?);
    let regex = regex::Regex::new(r"(\d+)_+.+")?;

    let mut m = Vec::new();
    for entry in std::fs::read_dir(src_dir)?.flatten() {
        if let Ok(filetype) = entry.file_type()
            && filetype.is_file()
            && let Some(c) = regex.captures(&entry.file_name().to_string_lossy())
        {
            let seq: usize = c.get(1).unwrap().as_str().parse().unwrap();
            if seq > isize::MAX as usize {
                panic!("Too many migrations!");
            }
            m.push((seq, entry.path()));
        }
    }

    m.sort_by_key(|a| a.0);

    out.write_all(b"[")?;
    for (seq, file_path) in m {
        let mut in_buf = std::io::BufReader::new(std::fs::File::open(&file_path)?);
        let mut data = Vec::new();

        in_buf.read_to_end(&mut data)?;
        write!(
            out,
            "({seq}isize,r###\"{}\"###,\"{}\",",
            file_path.to_string_lossy(),
            BASE64_URL_SAFE_NO_PAD.encode(sha1::Sha1::digest(&data))
        )?;
        out.write_all("r###\"".as_bytes())?;
        out.write_all(&data)?;
        out.write_all("\"###),\n".as_bytes())?;
    }
    out.write_all(b"]")?;
    Ok(())
}