paperclip_core/v3/models/
openapi.rs

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
use super::v2;

impl From<v2::DefaultApiRaw> for openapiv3::OpenAPI {
    fn from(v2: v2::DefaultApiRaw) -> Self {
        let mut spec = openapiv3::OpenAPI {
            openapi: "3.0.0".into(),
            tags: v2.tags.iter().cloned().map(From::from).collect(),
            info: v2.info.clone().into(),
            servers: openapi3_servers(v2.schemes, v2.host, v2.base_path),
            external_docs: v2.external_docs.map(From::from),
            ..Default::default()
        };

        let mut components = openapiv3::Components::default();
        for (name, scheme) in v2.security_definitions {
            components
                .security_schemes
                .insert(name, openapiv3::ReferenceOr::Item(scheme.into()));
        }
        components.responses = v2.responses.iter().fold(Default::default(), |mut i, b| {
            i.insert(b.0.to_string(), b.1.clone().into());
            i
        });
        spec.extensions = v2
            .extensions
            .into_iter()
            .fold(Default::default(), |mut i, (k, v)| {
                i.insert(k, v);
                i
            });
        spec.paths = openapiv3::Paths {
            paths: v2.paths.iter().fold(Default::default(), |mut i, b| {
                i.insert(
                    b.0.to_string(),
                    openapiv3::ReferenceOr::Item(b.1.clone().into()),
                );
                i
            }),
            ..Default::default()
        };

        components.schemas = v2.definitions.iter().fold(Default::default(), |mut i, b| {
            i.insert(b.0.to_string(), b.1.clone().into());
            i
        });
        spec.components = Some(components);

        spec
    }
}

fn openapi3_servers(
    schemes: std::collections::BTreeSet<v2::OperationProtocol>,
    host: Option<String>,
    base: Option<String>,
) -> Vec<openapiv3::Server> {
    if schemes.is_empty() && host.is_none() && base.is_none() {
        vec![]
    } else if let Some(host) = host {
        if !schemes.is_empty() {
            schemes
                .into_iter()
                .map(|scheme| {
                    let scheme_str = match scheme {
                        v2::OperationProtocol::Http => "http",
                        v2::OperationProtocol::Https => "https",
                        v2::OperationProtocol::Ws => "ws",
                        v2::OperationProtocol::Wss => "wss",
                    };
                    openapiv3::Server {
                        url: format!("{}://{}{}", scheme_str, host, base.as_deref().unwrap_or("")),
                        description: None,
                        variables: None,
                        extensions: Default::default(),
                    }
                })
                .collect()
        } else {
            vec![openapiv3::Server {
                url: format!("//{}{}", host, base.as_deref().unwrap_or("")),
                description: None,
                variables: None,
                extensions: Default::default(),
            }]
        }
    } else {
        vec![openapiv3::Server {
            url: base.unwrap_or_else(|| "/".to_string()),
            description: None,
            variables: None,
            extensions: Default::default(),
        }]
    }
}