rdf_fusion_functions/scalar/functional_form/
coalesce.rs

1use crate::scalar::dispatch::{
2    dispatch_n_ary_object_id, dispatch_n_ary_plain_term, dispatch_n_ary_typed_value,
3};
4use crate::scalar::sparql_op_impl::{
5    ScalarSparqlOpImpl, create_object_id_sparql_op_impl,
6    create_plain_term_sparql_op_impl, create_typed_value_sparql_op_impl,
7};
8use crate::scalar::{ScalarSparqlOp, ScalarSparqlOpSignature, SparqlOpArity};
9use rdf_fusion_encoding::object_id::ObjectIdEncoding;
10use rdf_fusion_encoding::plain_term::PlainTermEncoding;
11use rdf_fusion_encoding::typed_value::TypedValueEncoding;
12use rdf_fusion_extensions::functions::BuiltinName;
13use rdf_fusion_extensions::functions::FunctionName;
14use rdf_fusion_model::ThinError;
15
16#[derive(Debug, Hash, PartialEq, Eq)]
17pub struct CoalesceSparqlOp;
18
19impl Default for CoalesceSparqlOp {
20    fn default() -> Self {
21        Self::new()
22    }
23}
24
25impl CoalesceSparqlOp {
26    const NAME: FunctionName = FunctionName::Builtin(BuiltinName::Coalesce);
27
28    pub fn new() -> Self {
29        Self {}
30    }
31}
32
33impl ScalarSparqlOp for CoalesceSparqlOp {
34    fn name(&self) -> &FunctionName {
35        &Self::NAME
36    }
37
38    fn signature(&self) -> ScalarSparqlOpSignature {
39        ScalarSparqlOpSignature::default_with_arity(SparqlOpArity::Variadic)
40    }
41
42    fn typed_value_encoding_op(
43        &self,
44    ) -> Option<Box<dyn ScalarSparqlOpImpl<TypedValueEncoding>>> {
45        Some(create_typed_value_sparql_op_impl(|args| {
46            dispatch_n_ary_typed_value(
47                args.args.as_slice(),
48                args.number_rows,
49                |args| args.first().copied().ok_or(ThinError::ExpectedError),
50                |args| {
51                    args.iter()
52                        .find_map(|arg| arg.ok())
53                        .ok_or(ThinError::ExpectedError)
54                },
55            )
56        }))
57    }
58
59    fn plain_term_encoding_op(
60        &self,
61    ) -> Option<Box<dyn ScalarSparqlOpImpl<PlainTermEncoding>>> {
62        Some(create_plain_term_sparql_op_impl(|args| {
63            dispatch_n_ary_plain_term(
64                args.args.as_slice(),
65                args.number_rows,
66                |args| args.first().copied().ok_or(ThinError::ExpectedError),
67                |args| {
68                    args.iter()
69                        .find_map(|arg| arg.ok())
70                        .ok_or(ThinError::ExpectedError)
71                },
72            )
73        }))
74    }
75
76    fn object_id_encoding_op(
77        &self,
78        object_id_encoding: &ObjectIdEncoding,
79    ) -> Option<Box<dyn ScalarSparqlOpImpl<ObjectIdEncoding>>> {
80        let object_id_encoding = object_id_encoding.clone();
81        Some(create_object_id_sparql_op_impl(
82            &object_id_encoding.clone(),
83            move |args| {
84                dispatch_n_ary_object_id(
85                    &object_id_encoding,
86                    args.args.as_slice(),
87                    args.number_rows,
88                    |args| args.first().cloned().ok_or(ThinError::ExpectedError),
89                    |args| {
90                        args.iter()
91                            .find_map(|arg| (*arg).ok())
92                            .ok_or(ThinError::ExpectedError)
93                    },
94                )
95            },
96        ))
97    }
98}