rdf_fusion_functions/scalar/
sparql_op_impl.rs1use crate::scalar::ScalarSparqlOpArgs;
2use datafusion::arrow::datatypes::DataType;
3use datafusion::logical_expr::ColumnarValue;
4use rdf_fusion_encoding::TermEncoding;
5use rdf_fusion_encoding::object_id::ObjectIdEncoding;
6use rdf_fusion_encoding::plain_term::PlainTermEncoding;
7use rdf_fusion_encoding::typed_value::{TYPED_VALUE_ENCODING, TypedValueEncoding};
8use rdf_fusion_model::DFResult;
9
10pub trait ScalarSparqlOpImpl<TEncoding: TermEncoding> {
11 fn return_type(&self) -> DataType;
13
14 fn invoke(&self, args: ScalarSparqlOpArgs<TEncoding>) -> DFResult<ColumnarValue>;
16}
17
18pub struct ClosureSparqlOpImpl<TEncoding: TermEncoding> {
19 return_type: DataType,
20 closure: Box<dyn Fn(ScalarSparqlOpArgs<TEncoding>) -> DFResult<ColumnarValue>>,
21}
22
23impl<TEncoding: TermEncoding> ClosureSparqlOpImpl<TEncoding> {
24 pub fn new(
26 return_type: DataType,
27 closure: impl Fn(ScalarSparqlOpArgs<TEncoding>) -> DFResult<ColumnarValue> + 'static,
28 ) -> Self {
29 Self {
30 return_type,
31 closure: Box::new(closure),
32 }
33 }
34}
35
36impl<TEncoding: TermEncoding> ScalarSparqlOpImpl<TEncoding>
37 for ClosureSparqlOpImpl<TEncoding>
38{
39 fn return_type(&self) -> DataType {
40 self.return_type.clone()
41 }
42
43 fn invoke(&self, args: ScalarSparqlOpArgs<TEncoding>) -> DFResult<ColumnarValue> {
44 (self.closure)(args)
45 }
46}
47
48pub fn create_plain_term_sparql_op_impl(
49 closure: impl Fn(ScalarSparqlOpArgs<PlainTermEncoding>) -> DFResult<ColumnarValue>
50 + 'static,
51) -> Box<dyn ScalarSparqlOpImpl<PlainTermEncoding>> {
52 Box::new(ClosureSparqlOpImpl {
53 return_type: PlainTermEncoding::data_type(),
54 closure: Box::new(closure),
55 })
56}
57
58pub fn create_typed_value_sparql_op_impl(
59 closure: impl Fn(ScalarSparqlOpArgs<TypedValueEncoding>) -> DFResult<ColumnarValue>
60 + 'static,
61) -> Box<dyn ScalarSparqlOpImpl<TypedValueEncoding>> {
62 Box::new(ClosureSparqlOpImpl {
63 return_type: TYPED_VALUE_ENCODING.data_type(),
64 closure: Box::new(closure),
65 })
66}
67
68pub fn create_object_id_sparql_op_impl(
69 object_id_encoding: &ObjectIdEncoding,
70 closure: impl Fn(ScalarSparqlOpArgs<ObjectIdEncoding>) -> DFResult<ColumnarValue>
71 + 'static,
72) -> Box<dyn ScalarSparqlOpImpl<ObjectIdEncoding>> {
73 Box::new(ClosureSparqlOpImpl {
74 return_type: object_id_encoding.data_type(),
75 closure: Box::new(closure),
76 })
77}