rdf_fusion_functions/scalar/strings/
str_starts.rs

1use crate::scalar::dispatch::dispatch_binary_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::{
10    CompatibleStringArgs, StringLiteralRef, ThinError, TypedValueRef,
11};
12
13/// Implementation of the SPARQL `strstarts` function.
14#[derive(Debug, Hash, PartialEq, Eq)]
15pub struct StrStartsSparqlOp;
16
17impl Default for StrStartsSparqlOp {
18    fn default() -> Self {
19        Self::new()
20    }
21}
22
23impl StrStartsSparqlOp {
24    const NAME: FunctionName = FunctionName::Builtin(BuiltinName::StrStarts);
25
26    /// Creates a new [StrStartsSparqlOp].
27    pub fn new() -> Self {
28        Self {}
29    }
30}
31
32impl ScalarSparqlOp for StrStartsSparqlOp {
33    fn name(&self) -> &FunctionName {
34        &Self::NAME
35    }
36
37    fn signature(&self) -> ScalarSparqlOpSignature {
38        ScalarSparqlOpSignature::default_with_arity(SparqlOpArity::Fixed(2))
39    }
40
41    fn typed_value_encoding_op(
42        &self,
43    ) -> Option<Box<dyn ScalarSparqlOpImpl<TypedValueEncoding>>> {
44        Some(create_typed_value_sparql_op_impl(|args| {
45            dispatch_binary_typed_value(
46                &args.args[0],
47                &args.args[1],
48                |lhs_value, rhs_value| {
49                    let lhs_value = StringLiteralRef::try_from(lhs_value)?;
50                    let rhs_value = StringLiteralRef::try_from(rhs_value)?;
51                    let args = CompatibleStringArgs::try_from(lhs_value, rhs_value)?;
52                    Ok(TypedValueRef::BooleanLiteral(
53                        args.lhs.starts_with(args.rhs).into(),
54                    ))
55                },
56                |_, _| ThinError::expected(),
57            )
58        }))
59    }
60}