openapiv3_1/content.rs
1//! Implements content object for request body and response.
2use indexmap::IndexMap;
3use serde_json::Value;
4
5use super::encoding::Encoding;
6use super::example::Example;
7use super::extensions::Extensions;
8use super::{RefOr, Schema};
9
10/// Content holds request body content or response content.
11///
12/// [`Content`] implements OpenAPI spec [Media Type Object][media_type]
13///
14/// [media_type]: <https://spec.openapis.org/oas/latest.html#media-type-object>
15#[derive(serde_derive::Serialize, serde_derive::Deserialize, Default, Clone, PartialEq, bon::Builder)]
16#[cfg_attr(feature = "debug", derive(Debug))]
17#[builder(on(_, into))]
18#[non_exhaustive]
19pub struct Content {
20 /// Schema used in response body or request body.
21 #[serde(skip_serializing_if = "Option::is_none", default)]
22 pub schema: Option<Schema>,
23
24 /// Example for request body or response body.
25 #[serde(skip_serializing_if = "Option::is_none", default)]
26 pub example: Option<Value>,
27
28 /// Examples of the request body or response body. [`Content::examples`] should match to
29 /// media type and specified schema if present. [`Content::examples`] and
30 /// [`Content::example`] are mutually exclusive. If both are defined `examples` will
31 /// override value in `example`.
32 #[serde(skip_serializing_if = "IndexMap::is_empty", default)]
33 #[builder(default)]
34 pub examples: IndexMap<String, RefOr<Example>>,
35
36 /// A map between a property name and its encoding information.
37 ///
38 /// The key, being the property name, MUST exist in the [`Content::schema`] as a property, with
39 /// `schema` being a [`Schema::Object`] and this object containing the same property key in
40 /// [`Object::properties`](crate::schema::Object::properties).
41 ///
42 /// The encoding object SHALL only apply to `request_body` objects when the media type is
43 /// multipart or `application/x-www-form-urlencoded`.
44 #[serde(skip_serializing_if = "IndexMap::is_empty", default)]
45 #[builder(default)]
46 pub encoding: IndexMap<String, Encoding>,
47
48 /// Optional extensions "x-something".
49 #[serde(skip_serializing_if = "Option::is_none", default, flatten)]
50 pub extensions: Option<Extensions>,
51}
52
53impl Content {
54 /// Construct a new [`Content`] object for provided _`schema`_.
55 pub fn new<I: Into<Schema>>(schema: Option<I>) -> Self {
56 Self {
57 schema: schema.map(|schema| schema.into()),
58 ..Self::default()
59 }
60 }
61}
62
63impl<S: content_builder::IsComplete> From<ContentBuilder<S>> for Content {
64 fn from(builder: ContentBuilder<S>) -> Self {
65 builder.build()
66 }
67}