use std::fs;
use std::result::Result as StdResult;
use log::trace;
use minijinja::{Error as MinijinjaError, ErrorKind as MinijinjaErrorKind, Value, value::Kwargs};
pub fn function(path: String, options: Kwargs) -> StdResult<Value, MinijinjaError> {
trace!("file lookup - reading file: '{path}'");
let lstrip: bool = options.get::<Option<bool>>("lstrip")?.unwrap_or(false);
let rstrip: bool = options.get::<Option<bool>>("rstrip")?.unwrap_or(true);
trace!("file lookup - lstrip: {lstrip}, rstrip: {rstrip}");
let content = fs::read_to_string(&path).map_err(|e| {
MinijinjaError::new(
MinijinjaErrorKind::InvalidOperation,
format!("Failed to read file '{path}': {e}"),
)
})?;
let result = match (lstrip, rstrip) {
(true, true) => content.trim().to_string(),
(true, false) => content.trim_start().to_string(),
(false, true) => content.trim_end().to_string(),
(false, false) => content,
};
trace!("file lookup - returning {} characters", result.len());
options.assert_all_used()?;
Ok(Value::from(result))
}
#[cfg(test)]
mod tests {
use super::*;
use minijinja::Value;
use std::io::Write;
use tempfile::NamedTempFile;
#[test]
fn test_file_read_basic() {
let mut temp_file = NamedTempFile::new().unwrap();
writeln!(temp_file, "hello world").unwrap();
let kwargs = Kwargs::from_iter(std::iter::empty::<(&str, Value)>());
let result = function(temp_file.path().to_string_lossy().to_string(), kwargs);
assert!(result.is_ok());
assert_eq!(result.unwrap().as_str().unwrap(), "hello world");
}
#[test]
fn test_file_read_with_whitespace() {
let mut temp_file = NamedTempFile::new().unwrap();
writeln!(temp_file, " hello world ").unwrap();
let kwargs = Kwargs::from_iter(std::iter::empty::<(&str, Value)>());
let result = function(temp_file.path().to_string_lossy().to_string(), kwargs);
assert!(result.is_ok());
assert_eq!(result.unwrap().as_str().unwrap(), " hello world");
}
#[test]
fn test_file_read_lstrip() {
let mut temp_file = NamedTempFile::new().unwrap();
writeln!(temp_file, " hello world ").unwrap();
let kwargs = Kwargs::from_iter([("lstrip", Value::from(true))]);
let result = function(temp_file.path().to_string_lossy().to_string(), kwargs);
assert!(result.is_ok());
assert_eq!(result.unwrap().as_str().unwrap(), "hello world");
}
#[test]
fn test_file_read_no_strip() {
let mut temp_file = NamedTempFile::new().unwrap();
writeln!(temp_file, " hello world ").unwrap();
let kwargs = Kwargs::from_iter([("rstrip", Value::from(false))]);
let result = function(temp_file.path().to_string_lossy().to_string(), kwargs);
assert!(result.is_ok());
assert_eq!(result.unwrap().as_str().unwrap(), " hello world \n");
}
#[test]
fn test_file_not_found() {
let kwargs = Kwargs::from_iter(std::iter::empty::<(&str, Value)>());
let result = function("/nonexistent/file.txt".to_string(), kwargs);
assert!(result.is_err());
assert!(
result
.unwrap_err()
.to_string()
.contains("Failed to read file")
);
}
}