1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// =============================================================================
// Copyright (c) 2026 Haixing Hu.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0.
// =============================================================================
//! Number representations accepted by JSON decoding.
/// Controls lexical admission of syntactically valid JSON number tokens.
///
/// Typed decoding still lets Serde construct the requested target type, so its
/// numeric representation can depend on that type and the active Serde
/// features. Validated decoding constructs its owned value according to this
/// model and the selected number policy.
///
/// # Examples
///
/// The default model rejects an integer above `u64::MAX`. The finite fallback
/// admits it as an `f64`, which rounds this value and loses integer precision.
/// This example uses a controlled input and an unlimited decoder for
/// illustration; use finite limits for untrusted input. Typed decoding still
/// lets the target type and active features determine its representation. Use
/// a string or a domain-specific format when exact large integers are needed.
/// See [`JsonValidatedDecodeOptions`](crate::decode::JsonValidatedDecodeOptions)
/// and the [JSON number contract](https://github.com/qubit-ltd/rs-json/blob/main/doc/number_contract.md).
///
/// ```
/// use std::convert::Infallible;
///
/// use qubit_json::decode::JsonDecodeErrorKind;
/// use qubit_json::decode::JsonDecodeNumberModel;
/// use qubit_json::decode::JsonDecoder;
/// use qubit_json::decode::JsonNumberPolicy;
/// use qubit_json::decode::JsonValidatedDecodeError;
/// use qubit_json::decode::JsonValidatedDecodeOptions;
///
/// let input = "18446744073709551617";
/// let strict = JsonValidatedDecodeOptions::builder().build();
/// let error = JsonDecoder::unlimited()
/// .decode_unique_validated_str(input, &strict, |_, _| {
/// Ok::<_, Infallible>(JsonNumberPolicy::Preserve)
/// })
/// .expect_err("the default model rejects integers above u64::MAX");
/// match error {
/// JsonValidatedDecodeError::Decode { error, .. } => {
/// assert_eq!(error.kind(), JsonDecodeErrorKind::InvalidJson);
/// }
/// other => panic!("unexpected error: {other:?}"),
/// }
///
/// let fallback = JsonValidatedDecodeOptions::builder()
/// .number_model(JsonDecodeNumberModel::Integer64WithFiniteFallback)
/// .build();
/// let owner = JsonDecoder::unlimited()
/// .decode_unique_validated_str(input, &fallback, |_, _| {
/// Ok::<_, Infallible>(JsonNumberPolicy::Preserve)
/// })
/// .expect("finite fallback admits the token with rounding");
/// assert!(owner.as_value().is_f64());
/// assert_eq!(owner.as_value().as_f64(), Some(18446744073709551616_f64));
/// ```