summaryrefslogtreecommitdiff
path: root/src/model/ops.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-12-30 10:01:37 +0100
committerLaurenz <laurmaedje@gmail.com>2022-12-30 10:01:37 +0100
commit94cf7005e99a9055799a641ae6f00669c5ec7a63 (patch)
tree463e262e86348f0cf04295dd4dcc83fba6f4a4ea /src/model/ops.rs
parent68c6160a14be4e77b98cd704d9e641a03aefa332 (diff)
Forbid division by zero
Diffstat (limited to 'src/model/ops.rs')
-rw-r--r--src/model/ops.rs21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/model/ops.rs b/src/model/ops.rs
index 9da9b0cc..7acf917d 100644
--- a/src/model/ops.rs
+++ b/src/model/ops.rs
@@ -1,10 +1,11 @@
//! Operations on values.
+use std::cmp::Ordering;
+
use super::{Regex, Value};
use crate::diag::StrResult;
use crate::geom::{Axes, Axis, GenAlign, Length, Numeric, PartialStroke, Rel, Smart};
use crate::util::format_eco;
-use std::cmp::Ordering;
use Value::*;
/// Bail with a type mismatch error.
@@ -195,6 +196,10 @@ pub fn mul(lhs: Value, rhs: Value) -> StrResult<Value> {
/// Compute the quotient of two values.
pub fn div(lhs: Value, rhs: Value) -> StrResult<Value> {
+ if is_zero(&rhs) {
+ Err("cannot divide by zero")?;
+ }
+
Ok(match (lhs, rhs) {
(Int(a), Int(b)) => Float(a as f64 / b as f64),
(Int(a), Float(b)) => Float(a as f64 / b),
@@ -229,6 +234,20 @@ pub fn div(lhs: Value, rhs: Value) -> StrResult<Value> {
})
}
+/// Whether a value is a numeric zero.
+fn is_zero(v: &Value) -> bool {
+ match *v {
+ Int(v) => v == 0,
+ Float(v) => v == 0.0,
+ Length(v) => v.is_zero(),
+ Angle(v) => v.is_zero(),
+ Ratio(v) => v.is_zero(),
+ Relative(v) => v.is_zero(),
+ Fraction(v) => v.is_zero(),
+ _ => false,
+ }
+}
+
/// Try to divide two lengths.
fn try_div_length(a: Length, b: Length) -> StrResult<f64> {
a.try_div(b).ok_or_else(|| "cannot divide these two lengths".into())