use super::traits::FilterFunction;
use crate::functions::metadata::{ArgumentMetadata, FunctionMetadata, SyntaxVariants};
use minijinja::value::Kwargs;
use minijinja::{Error, ErrorKind, Value};
const HASH_ARG: ArgumentMetadata = ArgumentMetadata {
name: "string",
arg_type: "string",
required: true,
default: None,
description: "The string to hash",
};
pub struct Md5;
impl Md5 {
fn hash(input: &str) -> String {
use md5::{Digest, Md5 as Md5Hasher};
let mut hasher = Md5Hasher::new();
hasher.update(input.as_bytes());
format!("{:x}", hasher.finalize())
}
}
impl FilterFunction for Md5 {
const NAME: &'static str = "md5";
const METADATA: FunctionMetadata = FunctionMetadata {
name: "md5",
category: "hash",
description: "Compute MD5 hash of a string",
arguments: &[HASH_ARG],
return_type: "string",
examples: &["{{ md5(string=\"hello\") }}", "{{ \"hello\" | md5 }}"],
syntax: SyntaxVariants::FUNCTION_AND_FILTER,
};
fn call_as_function(kwargs: Kwargs) -> Result<Value, Error> {
let input: String = kwargs.get("string")?;
Ok(Value::from(Self::hash(&input)))
}
fn call_as_filter(value: &Value, _kwargs: Kwargs) -> Result<Value, Error> {
let input = value
.as_str()
.ok_or_else(|| Error::new(ErrorKind::InvalidOperation, "md5 requires a string"))?;
Ok(Value::from(Self::hash(input)))
}
}
pub struct Sha1;
impl Sha1 {
fn hash(input: &str) -> String {
use sha1::{Digest, Sha1 as Sha1Hasher};
let mut hasher = Sha1Hasher::new();
hasher.update(input.as_bytes());
format!("{:x}", hasher.finalize())
}
}
impl FilterFunction for Sha1 {
const NAME: &'static str = "sha1";
const METADATA: FunctionMetadata = FunctionMetadata {
name: "sha1",
category: "hash",
description: "Compute SHA-1 hash of a string",
arguments: &[HASH_ARG],
return_type: "string",
examples: &["{{ sha1(string=\"hello\") }}", "{{ \"hello\" | sha1 }}"],
syntax: SyntaxVariants::FUNCTION_AND_FILTER,
};
fn call_as_function(kwargs: Kwargs) -> Result<Value, Error> {
let input: String = kwargs.get("string")?;
Ok(Value::from(Self::hash(&input)))
}
fn call_as_filter(value: &Value, _kwargs: Kwargs) -> Result<Value, Error> {
let input = value
.as_str()
.ok_or_else(|| Error::new(ErrorKind::InvalidOperation, "sha1 requires a string"))?;
Ok(Value::from(Self::hash(input)))
}
}
pub struct Sha256;
impl Sha256 {
fn hash(input: &str) -> String {
use sha2::{Digest, Sha256 as Sha256Hasher};
let mut hasher = Sha256Hasher::new();
hasher.update(input.as_bytes());
format!("{:x}", hasher.finalize())
}
}
impl FilterFunction for Sha256 {
const NAME: &'static str = "sha256";
const METADATA: FunctionMetadata = FunctionMetadata {
name: "sha256",
category: "hash",
description: "Compute SHA-256 hash of a string",
arguments: &[HASH_ARG],
return_type: "string",
examples: &["{{ sha256(string=\"hello\") }}", "{{ \"hello\" | sha256 }}"],
syntax: SyntaxVariants::FUNCTION_AND_FILTER,
};
fn call_as_function(kwargs: Kwargs) -> Result<Value, Error> {
let input: String = kwargs.get("string")?;
Ok(Value::from(Self::hash(&input)))
}
fn call_as_filter(value: &Value, _kwargs: Kwargs) -> Result<Value, Error> {
let input = value
.as_str()
.ok_or_else(|| Error::new(ErrorKind::InvalidOperation, "sha256 requires a string"))?;
Ok(Value::from(Self::hash(input)))
}
}
pub struct Sha512;
impl Sha512 {
fn hash(input: &str) -> String {
use sha2::{Digest, Sha512 as Sha512Hasher};
let mut hasher = Sha512Hasher::new();
hasher.update(input.as_bytes());
format!("{:x}", hasher.finalize())
}
}
impl FilterFunction for Sha512 {
const NAME: &'static str = "sha512";
const METADATA: FunctionMetadata = FunctionMetadata {
name: "sha512",
category: "hash",
description: "Compute SHA-512 hash of a string",
arguments: &[HASH_ARG],
return_type: "string",
examples: &["{{ sha512(string=\"hello\") }}", "{{ \"hello\" | sha512 }}"],
syntax: SyntaxVariants::FUNCTION_AND_FILTER,
};
fn call_as_function(kwargs: Kwargs) -> Result<Value, Error> {
let input: String = kwargs.get("string")?;
Ok(Value::from(Self::hash(&input)))
}
fn call_as_filter(value: &Value, _kwargs: Kwargs) -> Result<Value, Error> {
let input = value
.as_str()
.ok_or_else(|| Error::new(ErrorKind::InvalidOperation, "sha512 requires a string"))?;
Ok(Value::from(Self::hash(input)))
}
}