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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
//! Implements [OpenAPI Example Object][example] can be used to define examples for
//! [`Response`][response]s and [`RequestBody`][request_body]s.
//!
//! [example]: https://spec.openapis.org/oas/latest.html#example-object
//! [response]: response/struct.Response.html
//! [request_body]: request_body/struct.RequestBody.html
use serde::{Deserialize, Serialize};
/// Implements [OpenAPI Example Object][example].
///
/// Example is used on path operations to describe possible response bodies.
///
/// [example]: https://spec.openapis.org/oas/latest.html#example-object
#[non_exhaustive]
#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct Example {
/// Short description for the [`Example`].
#[serde(default, skip_serializing_if = "String::is_empty")]
pub summary: String,
/// Long description for the [`Example`]. Value supports markdown syntax for rich text
/// representation.
#[serde(default, skip_serializing_if = "String::is_empty")]
pub description: String,
/// Embedded literal example value. [`Example::value`] and [`Example::external_value`] are
/// mutually exclusive.
///
/// Deprecated for non-JSON serialization targets in OpenAPI 3.2; prefer
/// [`Example::data_value`] and/or [`Example::serialized_value`].
#[serde(skip_serializing_if = "Option::is_none")]
pub value: Option<serde_json::Value>,
/// An example of the data structure, which must be valid against the relevant schema. Added
/// in OpenAPI 3.2. When present, [`Example::value`] must be absent.
///
/// See <https://spec.openapis.org/oas/v3.2.0.html#example-object>.
#[serde(skip_serializing_if = "Option::is_none")]
pub data_value: Option<serde_json::Value>,
/// An example of the serialized form of the value, including encoding and escaping. Added
/// in OpenAPI 3.2.
///
/// When [`Example::data_value`] is present this should be the serialization of that data.
#[serde(skip_serializing_if = "Option::is_none")]
pub serialized_value: Option<String>,
/// An URI that points to a literal example value. [`Example::external_value`] provides the
/// capability to references an example that cannot be easily included in JSON or YAML.
/// [`Example::value`] and [`Example::external_value`] are mutually exclusive.
#[serde(default, skip_serializing_if = "String::is_empty")]
pub external_value: String,
}
impl Example {
/// Construct a new empty [`Example`]. This is effectively same as calling [`Example::default`].
#[must_use]
pub fn new() -> Self {
Self::default()
}
/// Add or change a short description for the [`Example`]. Setting this to empty `String`
/// will make it not render in the generated OpenAPI document.
#[must_use]
pub fn summary<S: Into<String>>(mut self, summary: S) -> Self {
self.summary = summary.into();
self
}
/// Add or change a long description for the [`Example`]. Markdown syntax is supported for rich
/// text representation.
///
/// Setting this to empty `String` will make it not render in the generated
/// OpenAPI document.
#[must_use]
pub fn description<D: Into<String>>(mut self, description: D) -> Self {
self.description = description.into();
self
}
/// Add or change embedded literal example value. [`Example::value`] and
/// [`Example::external_value`] are mutually exclusive.
#[must_use]
pub fn value(mut self, value: serde_json::Value) -> Self {
self.value = Some(value);
self
}
/// Add or change the structured example data. Requires OpenAPI 3.2.
///
/// [`Example::data_value`] and [`Example::value`] are mutually exclusive.
#[must_use]
pub fn data_value(mut self, data_value: serde_json::Value) -> Self {
self.data_value = Some(data_value);
self
}
/// Add or change the serialized form of the example. Requires OpenAPI 3.2.
#[must_use]
pub fn serialized_value<S: Into<String>>(mut self, serialized_value: S) -> Self {
self.serialized_value = Some(serialized_value.into());
self
}
/// Add or change an URI that points to a literal example value. [`Example::external_value`]
/// provides the capability to references an example that cannot be easily included
/// in JSON or YAML. [`Example::value`] and [`Example::external_value`] are mutually exclusive.
///
/// Setting this to an empty String will make the field not to render in the generated OpenAPI
/// document.
#[must_use]
pub fn external_value<E: Into<String>>(mut self, external_value: E) -> Self {
self.external_value = external_value.into();
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_example() {
let example = Example::new();
assert!(example.summary.is_empty());
assert!(example.description.is_empty());
assert!(example.value.is_none());
assert!(example.external_value.is_empty());
let example = example.summary("summary");
assert_eq!(example.summary, "summary");
let example = example.description("description");
assert_eq!(example.description, "description");
let example = example.external_value("external_value");
assert_eq!(example.external_value, "external_value");
let example = example.value(serde_json::Value::String("value".to_owned()));
assert!(example.value.is_some());
assert_eq!(
example.value.unwrap(),
serde_json::Value::String("value".to_owned())
);
}
#[test]
fn example_openapi_3_2_fields_round_trip() {
let example = Example::new()
.data_value(serde_json::json!({ "lat": 10, "long": 60 }))
.serialized_value(r#"{"lat":10,"long":60}"#);
let value = serde_json::to_value(&example).expect("serialize");
assert_eq!(
value,
serde_json::json!({
"dataValue": { "lat": 10, "long": 60 },
"serializedValue": r#"{"lat":10,"long":60}"#
})
);
let parsed: Example = serde_json::from_value(value).expect("deserialize");
assert_eq!(parsed, example);
}
}