rdf_fusion_functions/scalar/
sparql_op_impl.rs

1use 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    /// Returns the return type of this operation.
12    fn return_type(&self) -> DataType;
13
14    /// Invokes the operation on the given `args`.
15    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    /// Create a new `ClosureSparqlOpImpl`.
25    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}