Skip to main content

valico/json_schema/validators/
multiple_of.rs

1use 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}