Skip to content

Commit 5df51a4

Browse files
fix: merge one of schemas
1 parent 3e0905d commit 5df51a4

1 file changed

Lines changed: 25 additions & 21 deletions

File tree

packages/breach/src/utoipa.rs

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,37 +16,26 @@ pub fn merge_responses(
1616
.flatten()
1717
.chunk_by(|(code, _)| code.clone())
1818
.into_iter()
19-
.filter_map(|(code, chunk)| {
19+
.map(|(code, chunk)| {
2020
let response = merge_response(
2121
StatusCode::from_bytes(code.as_bytes()).expect("valid status code"),
2222
chunk.map(|(_, response)| response),
2323
);
2424

25-
response.map(|response| (code, RefOr::T(response)))
25+
(code, RefOr::T(response))
2626
})
2727
.collect()
2828
}
2929

3030
/// Merge multiple [`RefOr<Response>`] into a single [`Response`].
31-
fn merge_response(
32-
code: StatusCode,
33-
responses: impl Iterator<Item = RefOr<Response>>,
34-
) -> Option<Response> {
35-
let mut responses = responses
36-
.filter_map(|response| match response {
37-
RefOr::Ref(_) => None,
38-
RefOr::T(response) => Some(response),
39-
})
40-
.collect::<Vec<_>>();
31+
fn merge_response(code: StatusCode, responses: impl Iterator<Item = RefOr<Response>>) -> Response {
32+
let responses = responses.filter_map(|response| match response {
33+
RefOr::Ref(_) => None,
34+
RefOr::T(response) => Some(response),
35+
});
4136

4237
let mut builder = ResponseBuilder::new();
4338

44-
if responses.is_empty() {
45-
return None;
46-
} else if responses.len() == 1 {
47-
return Some(responses.remove(0));
48-
}
49-
5039
if let Some(canonical_reason) = code.canonical_reason() {
5140
builder = builder.description(canonical_reason)
5241
}
@@ -64,7 +53,6 @@ fn merge_response(
6453
.into_iter(),
6554
);
6655

67-
// TODO: Merge content.
6856
if let Some(content) = content {
6957
builder.content(content_type, content)
7058
} else {
@@ -74,7 +62,7 @@ fn merge_response(
7462

7563
// TODO: Merge headers, extensions, links.
7664

77-
Some(builder.build())
65+
builder.build()
7866
}
7967

8068
fn merge_content(mut contents: impl ExactSizeIterator<Item = Content>) -> Option<Content> {
@@ -97,7 +85,7 @@ fn merge_content(mut contents: impl ExactSizeIterator<Item = Content>) -> Option
9785
}
9886

9987
if let Some(schema) = content.schema {
100-
one_of_builder = one_of_builder.item(schema);
88+
one_of_builder = merge_into_one_of_builder(one_of_builder, schema);
10189
}
10290

10391
// TODO: Merge extensions.
@@ -110,3 +98,19 @@ fn merge_content(mut contents: impl ExactSizeIterator<Item = Content>) -> Option
11098

11199
Some(builder.build())
112100
}
101+
102+
fn merge_into_one_of_builder(mut builder: OneOfBuilder, schema: RefOr<Schema>) -> OneOfBuilder {
103+
if let RefOr::T(schema) = schema {
104+
if let Schema::OneOf(one_of) = schema {
105+
for item in one_of.items {
106+
builder = merge_into_one_of_builder(builder, item);
107+
}
108+
109+
builder
110+
} else {
111+
builder.item(RefOr::T(schema))
112+
}
113+
} else {
114+
builder.item(schema)
115+
}
116+
}

0 commit comments

Comments
 (0)