1use crate::compiler::prelude::*;
2use ::sha1::Digest;
3
4fn sha1(value: Value) -> Resolved {
5 let value = value.try_bytes()?;
6 Ok(hex::encode(sha1::Sha1::digest(&value)).into())
7}
8
9#[derive(Clone, Copy, Debug)]
10pub struct Sha1;
11
12impl Function for Sha1 {
13 fn identifier(&self) -> &'static str {
14 "sha1"
15 }
16
17 fn usage(&self) -> &'static str {
18 "Calculates a [SHA-1](https://en.wikipedia.org/wiki/SHA-1) hash of the `value`."
19 }
20
21 fn category(&self) -> &'static str {
22 Category::Cryptography.as_ref()
23 }
24
25 fn return_kind(&self) -> u16 {
26 kind::BYTES
27 }
28
29 fn parameters(&self) -> &'static [Parameter] {
30 const PARAMETERS: &[Parameter] = &[Parameter::required(
31 "value",
32 kind::BYTES,
33 "The string to calculate the hash for.",
34 )];
35 PARAMETERS
36 }
37
38 fn examples(&self) -> &'static [Example] {
39 &[example! {
40 title: "Calculate sha1 hash",
41 source: r#"sha1("foo")"#,
42 result: Ok("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"),
43 }]
44 }
45
46 fn compile(
47 &self,
48 _state: &state::TypeState,
49 _ctx: &mut FunctionCompileContext,
50 arguments: ArgumentList,
51 ) -> Compiled {
52 let value = arguments.required("value");
53
54 Ok(Sha1Fn { value }.as_expr())
55 }
56}
57
58#[derive(Debug, Clone)]
59struct Sha1Fn {
60 value: Box<dyn Expression>,
61}
62
63impl FunctionExpression for Sha1Fn {
64 fn resolve(&self, ctx: &mut Context) -> Resolved {
65 let value = self.value.resolve(ctx)?;
66 sha1(value)
67 }
68
69 fn type_def(&self, _: &state::TypeState) -> TypeDef {
70 TypeDef::bytes().infallible()
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 test_function![
79 sha1 => Sha1;
80
81 sha {
82 args: func_args![value: "foo"],
83 want: Ok("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"),
84 tdef: TypeDef::bytes().infallible(),
85 }
86 ];
87}