sw4rm_rs/shared/
response.rs

1use std::collections::HashMap;
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4
5use crate::{
6    Spec,
7    reference::*,
8    shared::{
9        Parameter,
10        Schema,
11    },
12    openapi_v3_0::{
13        Link,
14        MediaType,
15    },
16};
17
18/// Response Object
19///
20/// Describes a single response from an API Operation, including design-time, static links to
21/// operations based on the response.
22#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq)]
23#[serde(default, rename_all = "camelCase")]
24pub struct Response {
25    // MARK: Common Fields
26
27    pub description: String,
28    #[serde(skip_serializing_if = "HashMap::is_empty")]
29    pub headers: HashMap<String, RefOr<Parameter>>,
30
31    /// Allows extensions to the Swagger Schema. The field name MUST begin with x-, for example,
32    /// x-internal-id. The value can be null, a primitive, an array or an object. See Vendor
33    /// Extensions for further details.
34    #[serde(flatten, skip_serializing_if = "HashMap::is_empty")]
35    pub x_fields: HashMap<String, Value>,
36
37    // MARK: OpenAPI v2 Fields
38
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub schema: Option<Schema>,
41    #[serde(skip_serializing_if = "HashMap::is_empty")]
42    pub examples: HashMap<String, Value>,
43
44    // MARK: OpenAPI v3 Fields
45
46    #[serde(skip_serializing_if = "HashMap::is_empty")]
47    pub content: HashMap<String, MediaType>,
48    #[serde(skip_serializing_if = "HashMap::is_empty")]
49    pub links: HashMap<String, RefOr<Link>>,
50}
51
52impl Resolvable for Response {
53    fn resolve(spec: &Spec, path: &String) -> Result<Self, ResolveError> {
54        let path = path.clone();
55        let reference: Reference = path.clone().try_into().unwrap();
56
57        match reference.kind {
58            ReferenceType::Response => {
59                if spec.semver_check("=2") {
60                    spec.responses.get(&reference.name)
61                        .ok_or_else(|| ResolveError::UnknownPathError(path))
62                        .and_then(|t| t.resolve(spec))
63                } else {
64                    spec.components
65                        .as_ref()
66                        .ok_or_else(|| ResolveError::UnknownPathError(path.clone()))
67                        .and_then(|c| c.responses.get(&reference.name).ok_or_else(|| ResolveError::UnknownPathError(path)))
68                        .and_then(|p| p.resolve(spec))
69                }
70            },
71            _ => Err(ResolveError::UnknownPathError(path)),
72        }
73    }
74}