rdf_fusion_functions/scalar/terms/
strlang.rs

1use crate::scalar::dispatch::dispatch_binary_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::{LanguageString, ThinError, TypedValue, TypedValueRef};
10
11/// Creates a new RDF literal from a plain literal and a language tag.
12///
13/// # Relevant Resources
14/// - [SPARQL 1.1 - STRLANG](https://www.w3.org/TR/sparql11-query/#func-strlang)
15#[derive(Debug, Hash, PartialEq, Eq)]
16pub struct StrLangSparqlOp;
17
18impl Default for StrLangSparqlOp {
19    fn default() -> Self {
20        Self::new()
21    }
22}
23
24impl StrLangSparqlOp {
25    const NAME: FunctionName = FunctionName::Builtin(BuiltinName::StrLang);
26
27    /// Creates a new [StrLangSparqlOp].
28    pub fn new() -> Self {
29        Self {}
30    }
31}
32
33impl ScalarSparqlOp for StrLangSparqlOp {
34    fn name(&self) -> &FunctionName {
35        &Self::NAME
36    }
37
38    fn signature(&self) -> ScalarSparqlOpSignature {
39        ScalarSparqlOpSignature::default_with_arity(SparqlOpArity::Fixed(2))
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_owned_typed_value(
46                &args.args[0],
47                &args.args[1],
48                |lhs_value, rhs_value| {
49                    if let (
50                        TypedValueRef::SimpleLiteral(lhs_literal),
51                        TypedValueRef::SimpleLiteral(rhs_literal),
52                    ) = (lhs_value, rhs_value)
53                    {
54                        Ok(TypedValue::LanguageStringLiteral(LanguageString {
55                            value: lhs_literal.value.to_owned(),
56                            language: rhs_literal.value.to_ascii_lowercase(),
57                        }))
58                    } else {
59                        ThinError::expected()
60                    }
61                },
62                |_, _| ThinError::expected(),
63            )
64        }))
65    }
66}