Skip to main content

utoipa/openapi/
link.rs

1//! Implements [Open API Link Object][link_object] for responses.
2//!
3//! [link_object]: https://spec.openapis.org/oas/latest.html#link-object
4use std::collections::BTreeMap;
5
6use serde::{Deserialize, Serialize};
7
8use super::extensions::Extensions;
9use super::{builder, Server};
10
11builder! {
12    LinkBuilder;
13
14    /// Implements [Open API Link Object][link_object] for responses.
15    ///
16    /// The `Link` represents possible design time link for a response. It does not guarantee
17    /// callers ability to invoke it but rather provides known relationship between responses and
18    /// other operations.
19    ///
20    /// For computing links, and providing instructions to execute them,
21    /// a runtime [expression][expression] is used for accessing values in an operation
22    /// and using them as parameters while invoking the linked operation.
23    ///
24    /// [expression]: https://spec.openapis.org/oas/latest.html#runtime-expressions
25    /// [link_object]: https://spec.openapis.org/oas/latest.html#link-object
26    #[derive(Serialize, Deserialize, Clone, PartialEq, Default)]
27    #[cfg_attr(feature = "debug", derive(Debug))]
28    #[non_exhaustive]
29    #[serde(rename_all = "camelCase")]
30    pub struct Link {
31        /// A relative or absolute URI reference to an OAS operation. This field is
32        /// mutually exclusive of the _`operation_id`_ field, and **must** point to an [Operation
33        /// Object][operation].
34        /// Relative _`operation_ref`_ values may be used to locate an existing [Operation
35        /// Object][operation] in the OpenAPI definition. See the rules for resolving [Relative
36        /// References][relative_references].
37        ///
38        /// [relative_references]: https://spec.openapis.org/oas/latest.html#relative-references-in-uris
39        /// [operation]: ../path/struct.Operation.html
40        #[serde(skip_serializing_if = "String::is_empty", default)]
41        pub operation_ref: String,
42
43        /// The name of an existing, resolvable OAS operation, as defined with a unique
44        /// _`operation_id`_.
45        /// This field is mutually exclusive of the _`operation_ref`_ field.
46        #[serde(skip_serializing_if = "String::is_empty", default)]
47        pub operation_id: String,
48
49        /// A map representing parameters to pass to an operation as specified with _`operation_id`_
50        /// or identified by _`operation_ref`_. The key is parameter name to be used and value can
51        /// be any value supported by JSON or an [expression][expression] e.g. `$path.id`
52        ///
53        /// [expression]: https://spec.openapis.org/oas/latest.html#runtime-expressions
54        #[serde(skip_serializing_if = "BTreeMap::is_empty")]
55        pub parameters: BTreeMap<String, serde_json::Value>,
56
57        /// A literal value or an [expression][expression] to be used as request body when operation is called.
58        ///
59        /// [expression]: https://spec.openapis.org/oas/latest.html#runtime-expressions
60        #[serde(skip_serializing_if = "Option::is_none")]
61        pub request_body: Option<serde_json::Value>,
62
63        /// Description of the link. Value supports Markdown syntax.
64        #[serde(skip_serializing_if = "String::is_empty", default)]
65        pub description: String,
66
67        /// A [`Server`][server] object to be used by the target operation.
68        ///
69        /// [server]: ../server/struct.Server.html
70        #[serde(skip_serializing_if = "Option::is_none")]
71        pub server: Option<Server>,
72
73        /// Optional extensions "x-something".
74        #[serde(skip_serializing_if = "Option::is_none", flatten)]
75        pub extensions: Option<Extensions>,
76    }
77}
78
79impl LinkBuilder {
80    /// Set a relative or absolute URI reference to an OAS operation. This field is
81    /// mutually exclusive of the _`operation_id`_ field, and **must** point to an [Operation
82    /// Object][operation].
83    ///
84    /// [operation]: ../path/struct.Operation.html
85    pub fn operation_ref<S: Into<String>>(mut self, operation_ref: S) -> Self {
86        self.operation_ref = operation_ref.into();
87
88        self
89    }
90
91    /// Set the name of an existing, resolvable OAS operation, as defined with a unique
92    /// _`operation_id`_.
93    /// This field is mutually exclusive of the _`operation_ref`_ field.
94    pub fn operation_id<S: Into<String>>(mut self, operation_id: S) -> Self {
95        self.operation_id = operation_id.into();
96
97        self
98    }
99
100    /// Add parameter to be passed to [Operation][operation] upon execution.
101    ///
102    /// [operation]: ../path/struct.Operation.html
103    pub fn parameter<N: Into<String>, V: Into<serde_json::Value>>(
104        mut self,
105        name: N,
106        value: V,
107    ) -> Self {
108        self.parameters.insert(name.into(), value.into());
109
110        self
111    }
112
113    /// Set a literal value or an [expression][expression] to be used as request body when operation is called.
114    ///
115    /// [expression]: https://spec.openapis.org/oas/latest.html#runtime-expressions
116    pub fn request_body<B: Into<serde_json::Value>>(mut self, request_body: Option<B>) -> Self {
117        self.request_body = request_body.map(|request_body| request_body.into());
118
119        self
120    }
121
122    /// Set description of the link. Value supports Markdown syntax.
123    pub fn description<S: Into<String>>(mut self, description: S) -> Self {
124        self.description = description.into();
125
126        self
127    }
128
129    /// Set a [`Server`][server] object to be used by the target operation.
130    ///
131    /// [server]: ../server/struct.Server.html
132    pub fn server<S: Into<Server>>(mut self, server: Option<S>) -> Self {
133        self.server = server.map(|server| server.into());
134
135        self
136    }
137
138    /// Add openapi extensions (x-something) of the API.
139    pub fn extensions(mut self, extensions: Option<Extensions>) -> Self {
140        self.extensions = extensions;
141
142        self
143    }
144}