use rust_embed::RustEmbed;
pub const TEMPLATE_VERSION: &str = "1.0.0";
#[derive(RustEmbed)]
#[folder = "templates/"]
pub struct Assets;
pub const DEFAULT_PLUGIN_VERSION: &str = "1.4.7";
pub struct RenderContext {
pub plugin_version: String,
}
impl Default for RenderContext {
fn default() -> Self {
Self {
plugin_version: DEFAULT_PLUGIN_VERSION.to_string(),
}
}
}
impl RenderContext {
pub fn with_version(version: impl Into<String>) -> Self {
Self {
plugin_version: version.into(),
}
}
}
pub fn render_template(path: &str, ctx: &RenderContext) -> Option<Vec<u8>> {
let file = Assets::get(path)?;
if path == "package.json.template" {
let content = std::str::from_utf8(&file.data).ok()?;
let rendered = content.replace("{{PLUGIN_VERSION}}", &ctx.plugin_version);
Some(rendered.into_bytes())
} else {
Some(file.data.into_owned())
}
}
pub fn template_to_output_path(template_path: &str) -> &'static str {
match template_path {
"plugins/ralph.ts" => "plugins/ralph.ts",
"commands/ralph-loop.md" => "commands/ralph-loop.md",
"commands/cancel-ralph.md" => "commands/cancel-ralph.md",
"commands/ralph-help.md" => "commands/ralph-help.md",
"package.json.template" => "package.json",
".gitignore.template" => ".gitignore",
_ => "",
}
}
pub fn canonical_templates() -> &'static [&'static str] {
&[
"plugins/ralph.ts",
"commands/ralph-loop.md",
"commands/cancel-ralph.md",
"commands/ralph-help.md",
"package.json.template",
".gitignore.template",
]
}
pub fn template_canonical_hash(path: &str, ctx: &RenderContext) -> Option<String> {
let bytes = render_template(path, ctx)?;
Some(crate::hash::sha256_hex(&bytes))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn all_canonical_templates_exist() {
let ctx = RenderContext::default();
for path in canonical_templates() {
let result = render_template(path, &ctx);
assert!(result.is_some(), "template not found: {path}");
}
}
#[test]
fn package_json_substitutes_version() {
let ctx = RenderContext::with_version("9.9.9");
let bytes = render_template("package.json.template", &ctx).unwrap();
let content = String::from_utf8(bytes).unwrap();
assert!(
content.contains("9.9.9"),
"version not substituted: {content}"
);
assert!(!content.contains("{{PLUGIN_VERSION}}"));
}
#[test]
fn default_version_is_correct() {
assert_eq!(DEFAULT_PLUGIN_VERSION, "1.4.7");
}
#[test]
fn template_to_output_path_mappings() {
assert_eq!(
template_to_output_path("plugins/ralph.ts"),
"plugins/ralph.ts"
);
assert_eq!(
template_to_output_path("package.json.template"),
"package.json"
);
assert_eq!(template_to_output_path(".gitignore.template"), ".gitignore");
}
}