use serde_json::Value;
use std::collections::HashMap;
use tera::TeraResult;
use crate::template::engine_adapter::{JsonRegisterExt, try_get_value};
enum VersionPart {
Major,
Minor,
Patch,
}
fn increment_version(v: &str, part: VersionPart) -> Result<String, tera::Error> {
let stripped = v.strip_prefix('v').unwrap_or(v);
let parts: Vec<&str> = stripped.splitn(3, '.').collect();
let invalid = || {
tera::Error::message(format!(
"incpatch/incminor/incmajor: '{}' is not a valid semver version (expected MAJOR.MINOR.PATCH)",
v
))
};
if parts.len() < 3 {
return Err(invalid());
}
let major: u64 = parts
.first()
.and_then(|s| s.parse().ok())
.ok_or_else(invalid)?;
let minor: u64 = parts
.get(1)
.and_then(|s| s.parse().ok())
.ok_or_else(invalid)?;
let patch: u64 = parts
.get(2)
.and_then(|s| {
s.split('-').next().and_then(|n| n.parse().ok())
})
.ok_or_else(invalid)?;
let prefix = if v.starts_with('v') { "v" } else { "" };
Ok(match part {
VersionPart::Major => format!("{}{}.0.0", prefix, major + 1),
VersionPart::Minor => format!("{}{}.{}.0", prefix, major, minor + 1),
VersionPart::Patch => format!("{}{}.{}.{}", prefix, major, minor, patch + 1),
})
}
pub(super) fn register(tera: &mut tera::Tera) {
tera.register_json_function(
"incpatch",
|args: &HashMap<String, Value>| -> TeraResult<Value> {
let v = args
.get("v")
.and_then(|v| v.as_str())
.ok_or_else(|| tera::Error::message("incpatch requires `v` argument"))?;
Ok(Value::String(increment_version(v, VersionPart::Patch)?))
},
);
tera.register_json_function(
"incminor",
|args: &HashMap<String, Value>| -> TeraResult<Value> {
let v = args
.get("v")
.and_then(|v| v.as_str())
.ok_or_else(|| tera::Error::message("incminor requires `v` argument"))?;
Ok(Value::String(increment_version(v, VersionPart::Minor)?))
},
);
tera.register_json_function(
"incmajor",
|args: &HashMap<String, Value>| -> TeraResult<Value> {
let v = args
.get("v")
.and_then(|v| v.as_str())
.ok_or_else(|| tera::Error::message("incmajor requires `v` argument"))?;
Ok(Value::String(increment_version(v, VersionPart::Major)?))
},
);
tera.register_json_filter("incpatch", |value: &Value, _: &HashMap<String, Value>| {
let v = try_get_value!("incpatch", "value", String, value);
Ok(Value::String(increment_version(&v, VersionPart::Patch)?))
});
tera.register_json_filter("incminor", |value: &Value, _: &HashMap<String, Value>| {
let v = try_get_value!("incminor", "value", String, value);
Ok(Value::String(increment_version(&v, VersionPart::Minor)?))
});
tera.register_json_filter("incmajor", |value: &Value, _: &HashMap<String, Value>| {
let v = try_get_value!("incmajor", "value", String, value);
Ok(Value::String(increment_version(&v, VersionPart::Major)?))
});
}