use base64::{Engine, engine::general_purpose};
use plf::{Kwargs, State, TeraResult};
pub fn b64_encode(val: &str, kwargs: Kwargs, _: &State) -> TeraResult<String> {
let url_safe = kwargs.get::<bool>("url_safe")?.unwrap_or(false);
if url_safe {
Ok(general_purpose::URL_SAFE.encode(val))
} else {
Ok(general_purpose::STANDARD.encode(val))
}
}
pub fn b64_decode(val: &str, kwargs: Kwargs, _: &State) -> TeraResult<String> {
let url_safe = kwargs.get::<bool>("url_safe")?.unwrap_or(false);
let decoded = if url_safe {
general_purpose::URL_SAFE.decode(val)
} else {
general_purpose::STANDARD.decode(val)
};
let bytes = decoded.map_err(|e| plf::Error::message(format!("Invalid base64: {e}")))?;
String::from_utf8(bytes).map_err(|e| plf::Error::message(format!("Invalid UTF-8: {e}")))
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Arc;
use plf::value::Map;
use plf::{Context, Kwargs, State};
#[test]
fn test_b64_encode() {
let ctx = Context::new();
let state = State::new(&ctx);
assert_eq!(
b64_encode("hello world", Kwargs::default(), &state).unwrap(),
"aGVsbG8gd29ybGQ="
);
}
#[test]
fn test_b64_encode_url_safe() {
let ctx = Context::new();
let state = State::new(&ctx);
let mut kwargs_map = Map::new();
kwargs_map.insert("url_safe".into(), true.into());
let kwargs = Kwargs::new(Arc::new(kwargs_map));
assert_eq!(b64_encode("<<??>>", kwargs, &state).unwrap(), "PDw_Pz4-");
}
#[test]
fn test_b64_decode() {
let ctx = Context::new();
let state = State::new(&ctx);
assert_eq!(
b64_decode("aGVsbG8gd29ybGQ=", Kwargs::default(), &state).unwrap(),
"hello world"
);
}
#[test]
fn test_b64_decode_url_safe() {
let ctx = Context::new();
let state = State::new(&ctx);
let mut kwargs_map = Map::new();
kwargs_map.insert("url_safe".into(), true.into());
let kwargs = Kwargs::new(Arc::new(kwargs_map));
assert_eq!(b64_decode("PDw_Pz4-", kwargs, &state).unwrap(), "<<??>>");
}
#[test]
fn test_b64_roundtrip() {
let ctx = Context::new();
let state = State::new(&ctx);
let original = "Hello, δΈη! π";
let encoded = b64_encode(original, Kwargs::default(), &state).unwrap();
let decoded = b64_decode(&encoded, Kwargs::default(), &state).unwrap();
assert_eq!(decoded, original);
}
#[test]
fn test_b64_decode_invalid() {
let ctx = Context::new();
let state = State::new(&ctx);
let result = b64_decode("not valid base64!!!", Kwargs::default(), &state);
assert!(result.is_err());
}
#[test]
fn test_register() {
let mut tera = plf::Tera::default();
tera.register_filter("b64_encode", b64_encode);
tera.register_filter("b64_decode", b64_decode);
}
}