diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-12-30 10:01:37 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-12-30 10:01:37 +0100 |
| commit | 94cf7005e99a9055799a641ae6f00669c5ec7a63 (patch) | |
| tree | 463e262e86348f0cf04295dd4dcc83fba6f4a4ea /src | |
| parent | 68c6160a14be4e77b98cd704d9e641a03aefa332 (diff) | |
Forbid division by zero
Diffstat (limited to 'src')
| -rw-r--r-- | src/model/ops.rs | 21 |
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()) |
