This commit is contained in:
2025-04-19 19:11:13 +02:00
parent 8f8016e748
commit 86bb165bf2
20 changed files with 3803 additions and 0 deletions

View File

@@ -0,0 +1,103 @@
use chrono::{DateTime, TimeZone, Utc};
use tera::{self, Function, Result, Value};
/// Registers custom Tera functions
pub fn register_tera_functions(tera: &mut tera::Tera) {
tera.register_function("now", NowFunction);
tera.register_function("format_date", FormatDateFunction);
}
/// Tera function to get the current date/time
#[derive(Clone)]
pub struct NowFunction;
impl Function for NowFunction {
fn call(&self, args: &std::collections::HashMap<String, Value>) -> Result<Value> {
let format = match args.get("format") {
Some(val) => match val.as_str() {
Some(s) => s,
None => "%Y-%m-%d %H:%M:%S",
},
None => "%Y-%m-%d %H:%M:%S",
};
let now = Utc::now();
// Special case for just getting the year
if args.get("year").and_then(|v| v.as_bool()).unwrap_or(false) {
return Ok(Value::String(now.format("%Y").to_string()));
}
Ok(Value::String(now.format(format).to_string()))
}
}
/// Tera function to format a date
#[derive(Clone)]
pub struct FormatDateFunction;
impl Function for FormatDateFunction {
fn call(&self, args: &std::collections::HashMap<String, Value>) -> Result<Value> {
let timestamp = match args.get("timestamp") {
Some(val) => match val.as_i64() {
Some(ts) => ts,
None => {
return Err(tera::Error::msg(
"The 'timestamp' argument must be a valid timestamp",
))
}
},
None => {
return Err(tera::Error::msg(
"The 'timestamp' argument is required",
))
}
};
let format = match args.get("format") {
Some(val) => match val.as_str() {
Some(s) => s,
None => "%Y-%m-%d %H:%M:%S",
},
None => "%Y-%m-%d %H:%M:%S",
};
// Convert timestamp to DateTime using the non-deprecated method
let datetime = match DateTime::from_timestamp(timestamp, 0) {
Some(dt) => dt,
None => {
return Err(tera::Error::msg(
"Failed to convert timestamp to datetime",
))
}
};
Ok(Value::String(datetime.format(format).to_string()))
}
}
/// Formats a date for display
pub fn format_date(date: &DateTime<Utc>, format: &str) -> String {
date.format(format).to_string()
}
/// Truncates a string to a maximum length and adds an ellipsis if truncated
pub fn truncate_string(s: &str, max_length: usize) -> String {
if s.len() <= max_length {
s.to_string()
} else {
format!("{}...", &s[0..max_length])
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_truncate_string() {
assert_eq!(truncate_string("Hello", 10), "Hello");
assert_eq!(truncate_string("Hello, world!", 5), "Hello...");
assert_eq!(truncate_string("", 5), "");
}
}