fhir_types/operation.rs
1// @generated by fhir-codegen from hl7.fhir.r4.core 4.0.1, hl7.fhir.r4b.core 4.3.0, hl7.fhir.r5.core 5.0.0, hl7.fhir.r6.core 6.0.0-ballot5, hl7.fhir.r3.core 3.0.2. DO NOT EDIT.
2// Change the emitter (tools/fhir-codegen) and regenerate.
3// SPDX-FileCopyrightText: Cadasto B.V.
4// SPDX-License-Identifier: Apache-2.0
5//! Runtime descriptors of the terminology operations.
6//!
7//! The exact parameter set each FHIR version declares
8//! (<https://hl7.org/fhir/R4B/operationdefinition.html>) plus the terminology
9//! ecosystem overlay (<https://hl7.org/fhir/uv/tx-ecosystem/requirements.html>),
10//! each parameter marked with its source, so a server accepts nothing more
11//! and nothing less.
12//!
13//! NOTE: a parameter is read from the primitive its definition declares and
14//! from the primitives that share that one's scalar in either direction, so a
15//! `canonical` parameter reads a `valueUri` too. No clause requires refusing
16//! the wider spelling, and the GET form carries no type marker at all
17//! (<https://hl7.org/fhir/R4B/operations.html>); the decision is recorded on
18//! #352.
19
20/// The direction of an operation parameter.
21#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub enum ParameterUse {
23 /// An input parameter.
24 In,
25 /// An output parameter.
26 Out,
27}
28
29/// Where a declared parameter comes from.
30#[derive(Debug, Clone, Copy, PartialEq, Eq)]
31pub enum ParameterSource {
32 /// The version's own `OperationDefinition`.
33 Version,
34 /// Pre-adopted from the FHIR R6 ballot for the terminology ecosystem.
35 PreAdopted,
36 /// Defined by the terminology ecosystem alone.
37 Ecosystem,
38}
39
40/// How many values a parameter takes.
41#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42pub struct Cardinality {
43 /// The minimum number of values.
44 pub min: u32,
45 /// The maximum number of values; `None` is unbounded (`*`).
46 pub max: Option<u32>,
47}
48
49impl Cardinality {
50 /// Whether `count` values satisfy this cardinality.
51 #[must_use]
52 pub const fn admits(self, count: u32) -> bool {
53 count >= self.min
54 && match self.max {
55 Some(max) => count <= max,
56 None => true,
57 }
58 }
59}
60
61/// One declared parameter, with its parts.
62#[derive(Debug, Clone, Copy, PartialEq, Eq)]
63pub struct Parameter {
64 /// The parameter name as it appears in `Parameters.parameter.name`.
65 pub name: &'static str,
66 /// The direction.
67 pub usage: ParameterUse,
68 /// The cardinality.
69 pub cardinality: Cardinality,
70 /// The FHIR type code, `None` for a multi-part parameter.
71 pub type_code: Option<&'static str>,
72 /// The invocation levels the parameter applies to; empty means every level.
73 pub scope: &'static [&'static str],
74 /// The nested parts.
75 pub parts: &'static [Parameter],
76 /// Where the parameter comes from.
77 pub source: ParameterSource,
78}
79
80impl Parameter {
81 /// The part named `name`, if any.
82 #[must_use]
83 pub fn part(&self, name: &str) -> Option<&'static Parameter> {
84 self.parts.iter().find(|part| part.name == name)
85 }
86}
87
88/// One operation as its version declares it.
89#[derive(Debug, Clone, Copy, PartialEq, Eq)]
90pub struct Operation {
91 /// The canonical URL of the `OperationDefinition`.
92 pub url: &'static str,
93 /// The resource type the operation applies to.
94 pub resource: &'static str,
95 /// The code used to invoke the operation, without the `$`.
96 pub code: &'static str,
97 /// Whether the operation is invoked at the system level.
98 pub system: bool,
99 /// Whether the operation is invoked at the resource type level.
100 pub type_level: bool,
101 /// Whether the operation is invoked on a resource instance.
102 pub instance: bool,
103 /// Every declared parameter, `in` and `out`, in declaration order.
104 pub parameters: &'static [Parameter],
105}
106
107impl Operation {
108 /// The parameter named `name` with the given direction, if declared.
109 #[must_use]
110 pub fn parameter(&self, usage: ParameterUse, name: &str) -> Option<&'static Parameter> {
111 self.parameters
112 .iter()
113 .find(|parameter| parameter.usage == usage && parameter.name == name)
114 }
115
116 /// The parameters of one direction, in declaration order.
117 pub fn parameters_of(&self, usage: ParameterUse) -> impl Iterator<Item = &'static Parameter> {
118 self.parameters
119 .iter()
120 .filter(move |parameter| parameter.usage == usage)
121 }
122}
123
124/// Why a `Parameters` resource does not fit an operation's declared
125/// parameter set. Every variant names the operation and the parameter.
126#[derive(Debug, Clone, PartialEq, Eq)]
127pub enum ParametersError {
128 /// A parameter has no name.
129 Unnamed {
130 /// The operation, as `Resource/$code`.
131 operation: &'static str,
132 },
133 /// A parameter the operation does not declare.
134 Undeclared {
135 /// The operation, as `Resource/$code`.
136 operation: &'static str,
137 /// The parameter name (dotted for a part).
138 name: std::string::String,
139 },
140 /// A parameter with a maximum of one given more than once.
141 Repeated {
142 /// The operation, as `Resource/$code`.
143 operation: &'static str,
144 /// The parameter name (dotted for a part).
145 name: &'static str,
146 },
147 /// A required parameter is absent.
148 Missing {
149 /// The operation, as `Resource/$code`.
150 operation: &'static str,
151 /// The parameter name (dotted for a part).
152 name: &'static str,
153 },
154 /// A parameter carries neither a value nor a resource.
155 MissingValue {
156 /// The operation, as `Resource/$code`.
157 operation: &'static str,
158 /// The parameter name (dotted for a part).
159 name: &'static str,
160 },
161 /// A parameter's value is not of the declared type.
162 WrongType {
163 /// The operation, as `Resource/$code`.
164 operation: &'static str,
165 /// The parameter name (dotted for a part).
166 name: &'static str,
167 /// The declared type.
168 expected: &'static str,
169 },
170}
171
172impl std::fmt::Display for ParametersError {
173 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
174 match self {
175 Self::Unnamed { operation } => {
176 write!(f, "{operation}: a parameter has no name")
177 }
178 Self::Undeclared { operation, name } => {
179 write!(f, "{operation}: parameter `{name}` is not declared")
180 }
181 Self::Repeated { operation, name } => {
182 write!(f, "{operation}: parameter `{name}` is given more than once")
183 }
184 Self::Missing { operation, name } => {
185 write!(f, "{operation}: parameter `{name}` is required")
186 }
187 Self::MissingValue { operation, name } => {
188 write!(f, "{operation}: parameter `{name}` has no value")
189 }
190 Self::WrongType {
191 operation,
192 name,
193 expected,
194 } => write!(f, "{operation}: parameter `{name}` is not a {expected}"),
195 }
196 }
197}
198
199impl std::error::Error for ParametersError {}