rdf_fusion_functions/scalar/strings/
sha1.rs

1use crate::scalar::dispatch::dispatch_unary_owned_typed_value;
2use crate::scalar::sparql_op_impl::{
3    ScalarSparqlOpImpl, create_typed_value_sparql_op_impl,
4};
5use crate::scalar::{ScalarSparqlOp, ScalarSparqlOpSignature, SparqlOpArity};
6use rdf_fusion_encoding::typed_value::TypedValueEncoding;
7use rdf_fusion_extensions::functions::BuiltinName;
8use rdf_fusion_extensions::functions::FunctionName;
9use rdf_fusion_model::{SimpleLiteral, ThinError, TypedValue, TypedValueRef};
10use sha1::{Digest, Sha1};
11
12#[derive(Debug, Hash, PartialEq, Eq)]
13pub struct Sha1SparqlOp;
14
15impl Default for Sha1SparqlOp {
16    fn default() -> Self {
17        Self::new()
18    }
19}
20
21impl Sha1SparqlOp {
22    const NAME: FunctionName = FunctionName::Builtin(BuiltinName::Sha1);
23
24    pub fn new() -> Self {
25        Self {}
26    }
27}
28
29impl ScalarSparqlOp for Sha1SparqlOp {
30    fn name(&self) -> &FunctionName {
31        &Self::NAME
32    }
33
34    fn signature(&self) -> ScalarSparqlOpSignature {
35        ScalarSparqlOpSignature::default_with_arity(SparqlOpArity::Fixed(1))
36    }
37
38    fn typed_value_encoding_op(
39        &self,
40    ) -> Option<Box<dyn ScalarSparqlOpImpl<TypedValueEncoding>>> {
41        Some(create_typed_value_sparql_op_impl(|args| {
42            dispatch_unary_owned_typed_value(
43                &args.args[0],
44                |value| {
45                    let string = match value {
46                        TypedValueRef::SimpleLiteral(value) => value.value,
47                        TypedValueRef::LanguageStringLiteral(value) => value.value,
48                        _ => return ThinError::expected(),
49                    };
50
51                    let mut hasher = Sha1::new();
52                    hasher.update(string);
53                    let result = hasher.finalize();
54                    let value = format!("{result:x}");
55
56                    Ok(TypedValue::SimpleLiteral(SimpleLiteral { value }))
57                },
58                ThinError::expected,
59            )
60        }))
61    }
62}