valico/json_schema/validators/
multiple_of.rs1use serde_json::Value;
2
3use super::super::errors;
4use super::super::scope;
5use std::cmp::Ordering;
6use std::f64;
7
8#[allow(missing_copy_implementations)]
9pub struct MultipleOf {
10 pub number: f64,
11}
12
13impl super::Validator for MultipleOf {
14 fn validate(
15 &self,
16 val: &Value,
17 path: &str,
18 _scope: &scope::Scope,
19 _: &super::ValidationState,
20 ) -> super::ValidationState {
21 let number = nonstrict_process!(val.as_f64(), path);
22
23 let valid = if (number.fract() == 0f64) && (self.number.fract() == 0f64) {
24 (number % self.number) == 0f64
25 } else {
26 let remainder: f64 = (number / self.number) % 1f64;
27 let remainder_less_than_epsilon = matches!(
28 remainder.partial_cmp(&f64::EPSILON),
29 None | Some(Ordering::Less)
30 );
31 let remainder_less_than_one = remainder < (1f64 - f64::EPSILON);
32 remainder_less_than_epsilon && remainder_less_than_one
33 };
34
35 if valid {
36 super::ValidationState::new()
37 } else {
38 val_error!(errors::MultipleOf {
39 path: path.to_string()
40 })
41 }
42 }
43}