Schemas

Numbers

f64 numbers, exact sized integers, f32, bounds, multiple_of and coercion from strings.

Constructors

ConstructorOutputNotes
vld::number()f64any JSON number
vld::number().int()i64a ZInt (= ZInteger<i64>); rejects fractions
vld::i8() … vld::i64(), vld::isize()the integer typeexact, range-checked
vld::u8() … vld::u64(), vld::usize()the integer typeexact, range-checked
vld::f32()f32rejects values outside the finite f32 range

Integers are read exactly: there is no f64 round trip, so vld::u64() accepts 18446744073709551615. A float with a fraction fails with not_int; a value outside the type range fails with too_small / too_big naming the type's bound.

use vld::prelude::*;

let port: u16 = vld::u16().min(1).parse("8080").unwrap();
assert_eq!(port, 8080);
assert!(vld::u16().parse("70000").is_err()); // above u16::MAX
assert!(vld::u8().parse("-1").is_err());
assert!(vld::i32().parse("1.5").is_err());   // not_int
assert_eq!(vld::u64().parse("18446744073709551615").unwrap(), u64::MAX);

Bounds

The same methods exist on number(), the integer schemas and f32(); the argument has the schema's own type (f64, u16, f32, …).

MethodCheckIssue
min(v) / gte(v)>= vtoo_small (inclusive)
max(v) / lte(v)<= vtoo_big (inclusive)
gt(v)> vtoo_small (exclusive)
lt(v)< vtoo_big (exclusive)
positive() / negative()> 0 / < 0too_small / too_big (exclusive)
non_negative() / non_positive()>= 0 / <= 0too_small / too_big
multiple_of(v)divisible by vnot_multiple_of
safe()within -(2^53 - 1)..=2^53 - 1not_safe_integer

When several bounds fail, the strictest one is reported. NaN never passes a bound.

multiple_of on floats uses a relative tolerance of 1e-9, so vld::number().multiple_of(0.1) accepts 0.3. A divisor of 0 rejects every value. vld::f32() compares at f32 precision, so vld::f32().max(0.1) accepts 0.1.

let price = vld::number().positive().multiple_of(0.01);
assert!(price.parse("19.99").is_ok());
assert!(price.parse("19.999").is_err());

let percent = vld::f32().min(0.0).max(100.0);
assert_eq!(percent.parse("12.5").unwrap(), 12.5_f32);

Coercion

By default only JSON numbers are accepted. coerce() also accepts numeric strings and booleans (true → 1, false → 0):

let n = vld::number().coerce();
assert_eq!(n.parse(r#""4.5""#).unwrap(), 4.5);
assert_eq!(n.parse("true").unwrap(), 1.0);
assert!(n.parse(r#""NaN""#).is_err());

let id = vld::u32().coerce();
assert_eq!(id.parse(r#""42""#).unwrap(), 42);

Web extractors coerce query, path, form, header and cookie values for you, so you rarely need coerce() there. See coercion rules.

Messages

  • type_error("...") — message for non-number input.
  • int_error("...") on integer schemas — message for a number with a fraction.
  • with_messages(|key| ...) — override by check key: too_small, too_big, not_positive, not_negative, not_non_negative, not_non_positive, not_multiple_of, not_safe, and not_int on integer schemas.

JSON Schema

number() emits {"type": "number"}, integers {"type": "integer", "format": "int8" … "uint64"} with minimum / maximum from the type range intersected with your bounds, and f32() {"type": "number", "format": "float"}.