const HASH_PREFIX: &str = "alef:hash:";
const HEADER_BODY: &str = "\
This file is auto-generated by alef — DO NOT EDIT.
To regenerate: alef generate
To verify freshness: alef verify --exit-code
Issues & docs: https://github.com/kreuzberg-dev/alef";
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CommentStyle {
DoubleSlash,
Hash,
Block,
}
pub fn header(style: CommentStyle) -> String {
match style {
CommentStyle::DoubleSlash => HEADER_BODY.lines().map(|l| format!("// {l}\n")).collect(),
CommentStyle::Hash => HEADER_BODY.lines().map(|l| format!("# {l}\n")).collect(),
CommentStyle::Block => {
let mut out = String::from("/*\n");
for line in HEADER_BODY.lines() {
out.push_str(&format!(" * {line}\n"));
}
out.push_str(" */\n");
out
}
}
}
const HEADER_MARKER: &str = "auto-generated by alef";
pub fn hash_content(content: &str) -> String {
blake3::hash(content.as_bytes()).to_hex().to_string()
}
pub fn inject_hash_line(content: &str, hash: &str) -> String {
let mut result = String::with_capacity(content.len() + 80);
let mut injected = false;
for (i, line) in content.lines().enumerate() {
result.push_str(line);
result.push('\n');
if !injected && i < 10 && line.contains(HEADER_MARKER) {
let trimmed = line.trim();
let hash_line = if trimmed.starts_with("//") {
format!("// {HASH_PREFIX}{hash}")
} else if trimmed.starts_with('#') {
format!("# {HASH_PREFIX}{hash}")
} else if trimmed.starts_with("/*") || trimmed.starts_with(" *") || trimmed.ends_with("*/") {
format!(" * {HASH_PREFIX}{hash}")
} else {
format!("// {HASH_PREFIX}{hash}")
};
result.push_str(&hash_line);
result.push('\n');
injected = true;
}
}
if !content.ends_with('\n') && result.ends_with('\n') {
result.pop();
}
result
}
pub fn extract_hash(content: &str) -> Option<String> {
for (i, line) in content.lines().enumerate() {
if i >= 10 {
break;
}
if let Some(pos) = line.find(HASH_PREFIX) {
let rest = &line[pos + HASH_PREFIX.len()..];
let hex = rest.trim().trim_end_matches("*/").trim();
if !hex.is_empty() {
return Some(hex.to_string());
}
}
}
None
}
pub fn strip_hash_line(content: &str) -> String {
let mut result = String::with_capacity(content.len());
for line in content.lines() {
if line.contains(HASH_PREFIX) {
continue;
}
result.push_str(line);
result.push('\n');
}
if !content.ends_with('\n') && result.ends_with('\n') {
result.pop();
}
result
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_header_double_slash() {
let h = header(CommentStyle::DoubleSlash);
assert!(h.contains("// This file is auto-generated by alef"));
assert!(h.contains("// Issues & docs: https://github.com/kreuzberg-dev/alef"));
}
#[test]
fn test_header_hash() {
let h = header(CommentStyle::Hash);
assert!(h.contains("# This file is auto-generated by alef"));
}
#[test]
fn test_header_block() {
let h = header(CommentStyle::Block);
assert!(h.starts_with("/*\n"));
assert!(h.contains(" * This file is auto-generated by alef"));
assert!(h.ends_with(" */\n"));
}
#[test]
fn test_inject_and_extract_rust() {
let h = header(CommentStyle::DoubleSlash);
let content = format!("{h}use foo;\n");
let hash = hash_content(&content);
let injected = inject_hash_line(&content, &hash);
assert!(injected.contains(HASH_PREFIX));
assert_eq!(extract_hash(&injected), Some(hash));
}
#[test]
fn test_inject_and_extract_python() {
let h = header(CommentStyle::Hash);
let content = format!("{h}import foo\n");
let hash = hash_content(&content);
let injected = inject_hash_line(&content, &hash);
assert!(injected.contains(&format!("# {HASH_PREFIX}")));
assert_eq!(extract_hash(&injected), Some(hash));
}
#[test]
fn test_inject_and_extract_c_block() {
let h = header(CommentStyle::Block);
let content = format!("{h}#include <stdio.h>\n");
let hash = hash_content(&content);
let injected = inject_hash_line(&content, &hash);
assert!(injected.contains(HASH_PREFIX));
assert_eq!(extract_hash(&injected), Some(hash));
}
#[test]
fn test_inject_php_line2() {
let h = header(CommentStyle::DoubleSlash);
let content = format!("<?php\n{h}namespace Foo;\n");
let hash = hash_content(&content);
let injected = inject_hash_line(&content, &hash);
let lines: Vec<&str> = injected.lines().collect();
assert_eq!(lines[0], "<?php");
assert!(lines[1].contains(HEADER_MARKER));
assert!(lines.iter().any(|l| l.contains(HASH_PREFIX)));
assert_eq!(extract_hash(&injected), Some(hash));
}
#[test]
fn test_no_header_returns_unchanged() {
let content = "fn main() {}\n";
let injected = inject_hash_line(content, "abc123");
assert_eq!(injected, content);
assert_eq!(extract_hash(&injected), None);
}
#[test]
fn test_strip_hash_line() {
let content = "// auto-generated by alef\n// alef:hash:abc123\nuse foo;\n";
let stripped = strip_hash_line(content);
assert_eq!(stripped, "// auto-generated by alef\nuse foo;\n");
}
#[test]
fn test_roundtrip() {
let h = header(CommentStyle::Hash);
let original = format!("{h}import sys\n");
let hash = hash_content(&original);
let injected = inject_hash_line(&original, &hash);
let stripped = strip_hash_line(&injected);
assert_eq!(stripped, original);
assert_eq!(hash_content(&stripped), hash);
}
}