Skip to main content

ergo_runtime/compute/implementations/divide/
impl.rs

1use std::collections::HashMap;
2
3use crate::common::Value;
4use crate::compute::{ComputeError, ComputePrimitive, ComputePrimitiveManifest, PrimitiveState};
5
6use super::manifest::divide_manifest;
7
8pub struct Divide {
9    manifest: ComputePrimitiveManifest,
10}
11
12impl Divide {
13    pub fn new() -> Self {
14        Self {
15            manifest: divide_manifest(),
16        }
17    }
18}
19
20impl Default for Divide {
21    fn default() -> Self {
22        Self::new()
23    }
24}
25
26impl ComputePrimitive for Divide {
27    fn manifest(&self) -> &ComputePrimitiveManifest {
28        &self.manifest
29    }
30
31    /// B.2: Strict divide - math-true semantics.
32    ///
33    /// Returns `Err(DivisionByZero)` when `b == 0.0`.
34    /// Returns `Err(NonFiniteResult)` when result overflows to inf.
35    ///
36    /// For fallback-on-zero behavior, use `safe_divide`.
37    ///
38    /// See: B.2 in PHASE_INVARIANTS.md
39    fn compute(
40        &self,
41        inputs: &HashMap<String, Value>,
42        _parameters: &HashMap<String, Value>,
43        _state: Option<&mut PrimitiveState>,
44    ) -> Result<HashMap<String, Value>, ComputeError> {
45        let a = inputs
46            .get("a")
47            .and_then(|v| v.as_number())
48            .expect("missing required numeric input 'a'");
49        let b = inputs
50            .get("b")
51            .and_then(|v| v.as_number())
52            .expect("missing required numeric input 'b'");
53
54        // B.2: Strict divide - error on zero or non-finite result.
55        if b == 0.0 {
56            return Err(ComputeError::DivisionByZero);
57        }
58
59        let result = a / b;
60        if !result.is_finite() {
61            return Err(ComputeError::NonFiniteResult);
62        }
63
64        Ok(HashMap::from([(
65            "result".to_string(),
66            Value::Number(result),
67        )]))
68    }
69}