sw4rm_rs/shared/
operation.rs

1use std::collections::HashMap;
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4
5use crate::{
6    Spec,
7    reference::*,
8    shared::{
9        ExternalDocumentation,
10        PathItem,
11        Parameter,
12        Response,
13        StringOrHttpCode,
14    },
15    openapi_v2::Scheme,
16    openapi_v3_0::{
17        RequestBody,
18        Server,
19    },
20};
21
22/// Operation Object
23///
24/// Describes a single API operation on a path.
25#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq)]
26#[serde(default, rename_all = "camelCase")]
27pub struct Operation {
28    // MARK: Common Fields
29
30    #[serde(skip_serializing_if = "Vec::is_empty")]
31    pub tags: Vec<String>,
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub summary: Option<String>,
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub description: Option<String>,
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub external_docs: Option<ExternalDocumentation>,
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub operation_id: Option<String>,
40    #[serde(skip_serializing_if = "Vec::is_empty")]
41    pub parameters: Vec<RefOr<Parameter>>,
42    #[serde(skip_serializing_if = "HashMap::is_empty")]
43    pub responses: HashMap<StringOrHttpCode, RefOr<Response>>,
44    #[serde(skip_serializing_if = "Option::is_none")]
45    pub deprecated: Option<bool>,
46    #[serde(skip_serializing_if = "Vec::is_empty")]
47    pub security: Vec<HashMap<String, Vec<String>>>,
48
49    /// Allows extensions to the Swagger Schema. The field name MUST begin with x-, for example,
50    /// x-internal-id. The value can be null, a primitive, an array or an object. See Vendor
51    /// Extensions for further details.
52    #[serde(flatten, skip_serializing_if = "HashMap::is_empty")]
53    pub x_fields: HashMap<String, Value>,
54
55    // MARK: OpenAPI v2 Fields
56
57    #[serde(skip_serializing_if = "Vec::is_empty")]
58    pub consumes: Vec<String>,
59    #[serde(skip_serializing_if = "Vec::is_empty")]
60    pub produces: Vec<String>,
61    #[serde(skip_serializing_if = "Vec::is_empty")]
62    pub schemes: Vec<Scheme>,
63
64    // MARK: OpenAPI v3 Fields
65
66    #[serde(skip_serializing_if = "Option::is_none")]
67    pub request_body: Option<RefOr<RequestBody>>,
68    // A potentially recursive type, so boxed
69    #[serde(skip_serializing_if = "HashMap::is_empty")]
70    pub callbacks: HashMap<String, Callback>,
71    #[serde(skip_serializing_if = "Vec::is_empty")]
72    pub servers: Vec<Server>,
73}
74
75#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
76pub struct Callback(RefOr<PathItem>);
77impl Resolvable for Callback {
78    fn resolve(spec: &Spec, path: &String) -> Result<Self, ResolveError> {
79        let path = path.clone();
80        let reference: Reference = path.clone().try_into().unwrap();
81
82        match reference.kind {
83            ReferenceType::Callbacks => {
84                spec.components
85                    .as_ref()
86                    .ok_or_else(|| ResolveError::UnknownPathError(path.clone()))
87                    .and_then(|c| c.callbacks.get(&reference.name).ok_or_else(|| ResolveError::UnknownPathError(path)))
88                    .and_then(|p| p.resolve(spec))
89            },
90            _ => Err(ResolveError::UnknownPathError(path)),
91        }
92    }
93}