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
//! Implements content object for request body and response.
use std::collections::BTreeMap;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use super::builder;
use super::example::Example;
use super::{encoding::Encoding, set_value, RefOr, Schema};
builder! {
ContentBuilder;
/// Content holds request body content or response content.
#[derive(Serialize, Deserialize, Default, Clone, PartialEq)]
#[cfg_attr(feature = "debug", derive(Debug))]
#[non_exhaustive]
pub struct Content {
/// Schema used in response body or request body.
pub schema: RefOr<Schema>,
/// Example for request body or response body.
#[serde(skip_serializing_if = "Option::is_none")]
pub example: Option<Value>,
/// Examples of the request body or response body. [`Content::examples`] should match to
/// media type and specified schema if present. [`Content::examples`] and
/// [`Content::example`] are mutually exclusive. If both are defined `examples` will
/// override value in `example`.
#[serde(skip_serializing_if = "BTreeMap::is_empty")]
pub examples: BTreeMap<String, RefOr<Example>>,
/// A map between a property name and its encoding information.
///
/// The key, being the property name, MUST exist in the [`Content::schema`] as a property, with
/// `schema` being a [`Schema::Object`] and this object containing the same property key in
/// [`Object::properties`](crate::openapi::schema::Object::properties).
///
/// The encoding object SHALL only apply to `request_body` objects when the media type is
/// multipart or `application/x-www-form-urlencoded`.
#[serde(skip_serializing_if = "BTreeMap::is_empty", default)]
pub encoding: BTreeMap<String, Encoding>,
}
}
impl Content {
pub fn new<I: Into<RefOr<Schema>>>(schema: I) -> Self {
Self {
schema: schema.into(),
..Self::default()
}
}
}
impl ContentBuilder {
/// Add schema.
pub fn schema<I: Into<RefOr<Schema>>>(mut self, component: I) -> Self {
set_value!(self schema component.into())
}
/// Add example of schema.
pub fn example(mut self, example: Option<Value>) -> Self {
set_value!(self example example)
}
/// Add iterator of _`(N, V)`_ where `N` is name of example and `V` is [`Example`][example] to
/// [`Content`] of a request body or response body.
///
/// [`Content::examples`] and [`Content::example`] are mutually exclusive. If both are defined
/// `examples` will override value in `example`.
///
/// [example]: ../example/Example.html
pub fn examples_from_iter<
E: IntoIterator<Item = (N, V)>,
N: Into<String>,
V: Into<RefOr<Example>>,
>(
mut self,
examples: E,
) -> Self {
self.examples.extend(
examples
.into_iter()
.map(|(name, example)| (name.into(), example.into())),
);
self
}
/// Add an encoding.
///
/// The `property_name` MUST exist in the [`Content::schema`] as a property,
/// with `schema` being a [`Schema::Object`] and this object containing the same property
/// key in [`Object::properties`](crate::openapi::schema::Object::properties).
///
/// The encoding object SHALL only apply to `request_body` objects when the media type is
/// multipart or `application/x-www-form-urlencoded`.
pub fn encoding<S: Into<String>, E: Into<Encoding>>(
mut self,
property_name: S,
encoding: E,
) -> Self {
self.encoding.insert(property_name.into(), encoding.into());
self
}
}