use serde_json::Value;
use std::collections::HashMap;
use tera::TeraResult;
use crate::template::engine_adapter::{JsonRegisterExt, try_get_value};
pub(super) fn register(tera: &mut tera::Tera) {
tera.register_json_filter("dir", |value: &Value, _: &HashMap<String, Value>| {
let s = try_get_value!("dir", "value", String, value);
let p = std::path::Path::new(&s);
Ok(Value::String(
p.parent()
.map(|p| p.to_string_lossy().to_string())
.unwrap_or_default(),
))
});
tera.register_json_filter("base", |value: &Value, _: &HashMap<String, Value>| {
let s = try_get_value!("base", "value", String, value);
let p = std::path::Path::new(&s);
Ok(Value::String(
p.file_name()
.map(|n| n.to_string_lossy().to_string())
.unwrap_or_default(),
))
});
tera.register_json_filter("abs", |value: &Value, _: &HashMap<String, Value>| {
let s = try_get_value!("abs", "value", String, value);
let p = std::path::Path::new(&s);
if p.is_absolute() {
Ok(Value::String(s))
} else {
let abs = std::env::current_dir()
.map(|cwd| cwd.join(p).to_string_lossy().to_string())
.unwrap_or(s);
Ok(Value::String(abs))
}
});
tera.register_json_filter(
"urlPathEscape",
|value: &Value, _: &HashMap<String, Value>| {
let s = try_get_value!("urlPathEscape", "value", String, value);
let encoded: String = s
.bytes()
.map(|b| {
if b.is_ascii_alphanumeric() || b == b'-' || b == b'_' || b == b'.' || b == b'~'
{
(b as char).to_string()
} else {
format!("%{:02X}", b)
}
})
.collect();
Ok(Value::String(encoded))
},
);
tera.register_json_function(
"dir",
|args: &HashMap<String, Value>| -> TeraResult<Value> {
let s = args
.get("s")
.and_then(|v| v.as_str())
.ok_or_else(|| tera::Error::message("dir requires `s` argument"))?;
let p = std::path::Path::new(s);
Ok(Value::String(
p.parent()
.map(|p| p.to_string_lossy().to_string())
.unwrap_or_default(),
))
},
);
tera.register_json_function(
"base",
|args: &HashMap<String, Value>| -> TeraResult<Value> {
let s = args
.get("s")
.and_then(|v| v.as_str())
.ok_or_else(|| tera::Error::message("base requires `s` argument"))?;
let p = std::path::Path::new(s);
Ok(Value::String(
p.file_name()
.map(|n| n.to_string_lossy().to_string())
.unwrap_or_default(),
))
},
);
tera.register_json_function(
"abs",
|args: &HashMap<String, Value>| -> TeraResult<Value> {
let s = args
.get("s")
.and_then(|v| v.as_str())
.ok_or_else(|| tera::Error::message("abs requires `s` argument"))?;
let p = std::path::Path::new(s);
if p.is_absolute() {
Ok(Value::String(s.to_string()))
} else {
let abs = std::env::current_dir()
.map(|cwd| cwd.join(p).to_string_lossy().to_string())
.unwrap_or_else(|_| s.to_string());
Ok(Value::String(abs))
}
},
);
tera.register_json_function(
"urlPathEscape",
|args: &HashMap<String, Value>| -> TeraResult<Value> {
let s = args
.get("s")
.and_then(|v| v.as_str())
.ok_or_else(|| tera::Error::message("urlPathEscape requires `s` argument"))?;
let encoded: String = s
.bytes()
.map(|b| {
if b.is_ascii_alphanumeric() || b == b'-' || b == b'_' || b == b'.' || b == b'~'
{
(b as char).to_string()
} else {
format!("%{:02X}", b)
}
})
.collect();
Ok(Value::String(encoded))
},
);
}