rdf_fusion_functions/scalar/functional_form/
coalesce.rs1use 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}