paperclip_core/v3/models/
operation.rs

1use super::{v2, Either, OperationEitherResponse};
2
3impl From<v2::Operation<v2::DefaultParameterRaw, v2::DefaultResponseRaw>> for openapiv3::Operation {
4    fn from(v2: v2::Operation<v2::DefaultParameterRaw, v2::DefaultResponseRaw>) -> Self {
5        let mut request_body: Option<openapiv3::RequestBody> = None;
6        let mut form_data: Option<openapiv3::AnySchema> = None;
7        let v2v = v2.clone();
8
9        let parameters = v2
10            .parameters
11            .iter()
12            .filter_map(|p| match p {
13                Either::Left(reference) => Some(reference.into()),
14                Either::Right(parameter) => {
15                    let either: Either<
16                        openapiv3::Parameter,
17                        Either<openapiv3::RequestBody, Option<openapiv3::Schema>>,
18                    > = parameter.clone().into();
19                    match either {
20                        Either::Right(r) => match r {
21                            Either::Left(l) => {
22                                request_body = Some(l);
23                                None
24                            }
25                            Either::Right(Some(schema)) => {
26                                if let Some(any) = form_data.as_mut() {
27                                    any.properties.insert(
28                                        parameter.name.clone(),
29                                        openapiv3::ReferenceOr::Item(Box::new(schema)),
30                                    );
31                                } else {
32                                    let mut any = openapiv3::AnySchema::default();
33                                    if parameter.required {
34                                        any.required.push(parameter.name.clone());
35                                    }
36                                    any.properties.insert(
37                                        parameter.name.clone(),
38                                        openapiv3::ReferenceOr::Item(Box::new(schema)),
39                                    );
40                                    form_data = Some(any);
41                                }
42                                None
43                            }
44                            Either::Right(None) => None,
45                        },
46                        Either::Left(parameter) => Some(openapiv3::ReferenceOr::Item(parameter)),
47                    }
48                }
49            })
50            .collect();
51
52        let request_body = if let Some(request_body) = request_body {
53            Some(openapiv3::ReferenceOr::Item(request_body))
54        } else if let Some(form_data) = form_data {
55            let mut request_body = openapiv3::RequestBody::default();
56            match v2.consumes {
57                None => None,
58                Some(consumes) => {
59                    for media in consumes {
60                        request_body.content.insert(media.0.to_string(), {
61                            openapiv3::MediaType {
62                                schema: Some(openapiv3::ReferenceOr::Item(openapiv3::Schema {
63                                    schema_data: Default::default(),
64                                    schema_kind: openapiv3::SchemaKind::Any(form_data.clone()),
65                                })),
66                                ..Default::default()
67                            }
68                        });
69                    }
70
71                    Some(openapiv3::ReferenceOr::Item(request_body))
72                }
73            }
74        } else {
75            None
76        };
77
78        openapiv3::Operation {
79            tags: v2.tags,
80            summary: v2.summary,
81            description: v2.description,
82            external_docs: None,
83            operation_id: v2.operation_id,
84            parameters,
85            request_body,
86            responses: openapiv3::Responses {
87                default: None,
88                responses: v2.responses.iter().fold(
89                    openapiv3::Responses::default().responses,
90                    |mut i, (k, v)| {
91                        if let Ok(code) = k.parse::<u16>() {
92                            let code = openapiv3::StatusCode::Code(code);
93                            i.insert(
94                                code,
95                                OperationEitherResponse {
96                                    operation: &v2v,
97                                    response: v,
98                                }
99                                .into(),
100                            );
101                        }
102                        i
103                    },
104                ),
105                ..Default::default()
106            },
107            deprecated: v2.deprecated,
108            security: if v2.security.is_empty() {
109                None
110            } else {
111                Some(
112                    v2.security
113                        .iter()
114                        .map(|s| {
115                            s.iter().fold(
116                                openapiv3::SecurityRequirement::default(),
117                                |mut i, (k, v)| {
118                                    i.insert(k.to_string(), v.clone());
119                                    i
120                                },
121                            )
122                        })
123                        .collect(),
124                )
125            },
126            servers: vec![],
127            extensions: Default::default(),
128            callbacks: Default::default(),
129        }
130    }
131}