jsonschema/keywords/
helpers.rs

1use serde_json::{Map, Value};
2
3use crate::{compiler, paths::Location, types::JsonType, ValidationError};
4
5#[inline]
6pub(crate) fn map_get_u64<'a>(
7    m: &'a Map<String, Value>,
8    ctx: &compiler::Context,
9    type_name: &str,
10) -> Option<Result<u64, ValidationError<'a>>> {
11    let value = m.get(type_name)?;
12    match value.as_u64() {
13        Some(n) => Some(Ok(n)),
14        None if value.is_i64() => Some(Err(ValidationError::minimum(
15            Location::new(),
16            ctx.location().clone(),
17            value,
18            0.into(),
19        ))),
20        None => {
21            if let Some(value) = value.as_f64() {
22                if value.trunc() == value {
23                    // NOTE: Imprecise cast as big integers are not supported yet
24                    #[allow(clippy::cast_possible_truncation)]
25                    return Some(Ok(value as u64));
26                }
27            }
28            Some(Err(ValidationError::single_type_error(
29                Location::new(),
30                ctx.location().clone(),
31                value,
32                JsonType::Integer,
33            )))
34        }
35    }
36}
37
38/// Fail if the input value is not `u64`.
39pub(crate) fn fail_on_non_positive_integer(
40    value: &Value,
41    instance_path: Location,
42) -> ValidationError<'_> {
43    if value.is_i64() {
44        ValidationError::minimum(Location::new(), instance_path, value, 0.into())
45    } else {
46        ValidationError::single_type_error(Location::new(), instance_path, value, JsonType::Integer)
47    }
48}