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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//! [`Strict`]: an opt-in wrapper that rejects unknown fields on
//! deserialize.
use ;
use ;
/// Deserialize `T` strictly: an unrecognized field is a `serde::de::Error`
/// instead of being ignored.
///
/// `T::deserialize` alone stays tolerant of unknown fields, unconditionally
/// (rule S8) — that default does not change. `Strict<T>` is a separate,
/// additive entry point for a caller who wants the opposite for one
/// particular call, such as validating a hand-written JSON fixture for
/// typos. See the spec's strict-mode section (rule S13) for the full
/// rationale, including why this is a distinct type rather than a flag on
/// the existing one.
///
/// A `Deserialize` implementation exists for `Strict<T>` for every
/// object-shaped type in this crate — [`crate::Message`],
/// [`crate::ControlAct`], [`crate::Element`], the five data types, and the
/// six RIM classes. [`crate::NullFlavor`] is a bare string that accepts
/// any code by design, so it has no `Strict` form.
///
/// **Strictness nests.** `Strict<Message>` rejects an unrecognized key not
/// only on the message object itself but inside its identifiers, its
/// control act, that act's trigger-event code, and every element of the
/// domain payload's tree — a typo four levels down is caught the same as
/// one at the top.
///
/// As rule S11 asks of every wrapper type in this crate, `Strict<T>`
/// implements `Deref`, `DerefMut`, and `From` both ways, plus a
/// `Serialize` impl that delegates to `T`'s own — strictness is a
/// deserialize-only concept, but a `Strict<T>` should still be usable
/// anywhere a `T` is.
///
/// Example:
///
/// ```
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// use serde_hl7_v3::{Ii, Strict};
///
/// let good = r#"{"root":"1.2.3","extension":"7"}"#;
/// let typo = r#"{"root":"1.2.3","extention":"7"}"#;
///
/// // The plain type ignores the mistyped optional key — and silently
/// // reads `extension` as absent. `Strict<Ii>` reports it:
/// assert_eq!(serde_json::from_str::<Ii>(typo)?.extension, None);
/// assert!(serde_json::from_str::<Strict<Ii>>(typo).is_err());
/// assert!(serde_json::from_str::<Strict<Ii>>(good).is_ok());
/// # Ok(())
/// # }
/// ```
;
// The reverse `From<Strict<T>> for T` cannot be written generically over
// `T` — Rust's orphan rule rejects `impl<T> From<Strict<T>> for T` because
// the `Self` type, `T`, would be a completely uncovered impl parameter.
// Each object wrapper gets its own concrete impl instead, written by the
// `object_wrapper!` macro alongside the type.