rdf_fusion_functions/scalar/numeric/
div.rs1use crate::scalar::dispatch::dispatch_binary_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::{Decimal, Numeric, NumericPair, ThinError, TypedValueRef};
10
11#[derive(Debug, Hash, PartialEq, Eq)]
13pub struct DivSparqlOp;
14
15impl Default for DivSparqlOp {
16 fn default() -> Self {
17 Self::new()
18 }
19}
20
21impl DivSparqlOp {
22 const NAME: FunctionName = FunctionName::Builtin(BuiltinName::Div);
23
24 pub fn new() -> Self {
26 Self {}
27 }
28}
29
30impl ScalarSparqlOp for DivSparqlOp {
31 fn name(&self) -> &FunctionName {
32 &Self::NAME
33 }
34
35 fn signature(&self) -> ScalarSparqlOpSignature {
36 ScalarSparqlOpSignature::default_with_arity(SparqlOpArity::Fixed(2))
37 }
38
39 fn typed_value_encoding_op(
40 &self,
41 ) -> Option<Box<dyn ScalarSparqlOpImpl<TypedValueEncoding>>> {
42 Some(create_typed_value_sparql_op_impl(|args| {
43 dispatch_binary_typed_value(
44 &args.args[0],
45 &args.args[1],
46 |lhs_value, rhs_value| {
47 if let (
48 TypedValueRef::NumericLiteral(lhs_numeric),
49 TypedValueRef::NumericLiteral(rhs_numeric),
50 ) = (lhs_value, rhs_value)
51 {
52 match NumericPair::with_casts_from(lhs_numeric, rhs_numeric) {
53 NumericPair::Int(lhs, rhs) => {
54 Decimal::from(lhs).checked_div(rhs).map(Numeric::Decimal)
55 }
56 NumericPair::Integer(lhs, rhs) => {
57 Decimal::from(lhs).checked_div(rhs).map(Numeric::Decimal)
58 }
59 NumericPair::Float(lhs, rhs) => Ok(Numeric::Float(lhs / rhs)),
60 NumericPair::Double(lhs, rhs) => {
61 Ok(Numeric::Double(lhs / rhs))
62 }
63 NumericPair::Decimal(lhs, rhs) => {
64 lhs.checked_div(rhs).map(Numeric::Decimal)
65 }
66 }
67 .map(TypedValueRef::NumericLiteral)
68 } else {
69 ThinError::expected()
70 }
71 },
72 |_, _| ThinError::expected(),
73 )
74 }))
75 }
76}