@@ -2,8 +2,9 @@ use indexmap::IndexMap;
22use openapiv3:: { Components , ExternalDocumentation , OpenAPI , Paths } ;
33
44use crate :: Error ;
5+ use crate :: Result ;
56
6- pub ( crate ) fn merge_all_openapi_specs ( openapi_specs : Vec < OpenAPI > ) -> crate :: Result < OpenAPI > {
7+ pub ( crate ) fn merge_all_openapi_specs ( openapi_specs : Vec < OpenAPI > ) -> Result < OpenAPI > {
78 if openapi_specs. is_empty ( ) {
89 Err ( Error :: unexpected ( "No OpenAPI specs provided" ) )
910 } else if openapi_specs. len ( ) == 1 {
@@ -22,7 +23,7 @@ pub(crate) fn merge_all_openapi_specs(openapi_specs: Vec<OpenAPI>) -> crate::Res
2223 }
2324}
2425
25- fn merge_openapi_specs ( a : OpenAPI , b : OpenAPI ) -> crate :: Result < OpenAPI > {
26+ fn merge_openapi_specs ( a : OpenAPI , b : OpenAPI ) -> Result < OpenAPI > {
2627 let openapi_version = {
2728 if a. openapi != b. openapi {
2829 return Err ( Error :: unexpected ( "OpenAPI versions do not match" ) ) ;
@@ -60,17 +61,17 @@ fn merge_openapi_specs(a: OpenAPI, b: OpenAPI) -> crate::Result<OpenAPI> {
6061 paths : b_paths,
6162 extensions : b_extensions,
6263 } = b. paths ;
63- let all_paths = merge_unique ( a_paths, b_paths) ;
64- let all_extensions = merge_unique ( a_extensions, b_extensions) ;
64+ let all_paths = merge_unique ( a_paths, b_paths) ? ;
65+ let all_extensions = merge_unique ( a_extensions, b_extensions) ? ;
6566 Paths {
6667 paths : all_paths,
6768 extensions : all_extensions,
6869 }
6970 } ;
7071
71- let components = merge_components ( a. components , b. components ) ;
72+ let components = merge_components ( a. components , b. components ) ? ;
7273 let security = merge_unique_option_list ( a. security , b. security ) ;
73- let extensions = merge_unique ( a. extensions , b. extensions ) ;
74+ let extensions = merge_unique ( a. extensions , b. extensions ) ? ;
7475
7576 let external_docs = merge_external_docs ( a. external_docs , b. external_docs ) ?;
7677
@@ -89,8 +90,8 @@ fn merge_openapi_specs(a: OpenAPI, b: OpenAPI) -> crate::Result<OpenAPI> {
8990 Ok ( result)
9091}
9192
92- fn merge_components ( a : Option < Components > , b : Option < Components > ) -> Option < Components > {
93- match ( a, b) {
93+ fn merge_components ( a : Option < Components > , b : Option < Components > ) -> Result < Option < Components > > {
94+ let result = match ( a, b) {
9495 ( Some ( a) , Some ( b) ) => {
9596 let Components {
9697 schemas : a_schemas,
@@ -119,23 +120,25 @@ fn merge_components(a: Option<Components>, b: Option<Components>) -> Option<Comp
119120 } = b;
120121
121122 let merged = Components {
122- schemas : merge_unique ( a_schemas, b_schemas) ,
123- responses : merge_unique ( a_responses, b_responses) ,
124- parameters : merge_unique ( a_parameters, b_parameters) ,
125- examples : merge_unique ( a_examples, b_examples) ,
126- request_bodies : merge_unique ( a_request_bodies, b_request_bodies) ,
127- headers : merge_unique ( a_headers, b_headers) ,
128- security_schemes : merge_unique ( a_security_schemes, b_security_schemes) ,
129- links : merge_unique ( a_links, b_links) ,
130- callbacks : merge_unique ( a_callbacks, b_callbacks) ,
131- extensions : merge_unique ( a_extensions, b_extensions) ,
123+ schemas : merge_unique ( a_schemas, b_schemas) ? ,
124+ responses : merge_unique ( a_responses, b_responses) ? ,
125+ parameters : merge_unique ( a_parameters, b_parameters) ? ,
126+ examples : merge_unique ( a_examples, b_examples) ? ,
127+ request_bodies : merge_unique ( a_request_bodies, b_request_bodies) ? ,
128+ headers : merge_unique ( a_headers, b_headers) ? ,
129+ security_schemes : merge_unique ( a_security_schemes, b_security_schemes) ? ,
130+ links : merge_unique ( a_links, b_links) ? ,
131+ callbacks : merge_unique ( a_callbacks, b_callbacks) ? ,
132+ extensions : merge_unique ( a_extensions, b_extensions) ? ,
132133 } ;
133134 Some ( merged)
134135 }
135136 ( Some ( a) , None ) => Some ( a) ,
136137 ( None , Some ( b) ) => Some ( b) ,
137138 ( None , None ) => None ,
138- }
139+ } ;
140+
141+ Ok ( result)
139142}
140143
141144fn merge_external_docs (
@@ -179,7 +182,7 @@ fn merge_external_docs(
179182 a_url
180183 } ;
181184
182- let extensions = merge_unique ( a_extensions, b_extensions) ;
185+ let extensions = merge_unique ( a_extensions, b_extensions) ? ;
183186
184187 Some ( ExternalDocumentation {
185188 description,
@@ -211,26 +214,27 @@ fn merge_unique_option_list<Key, Item>(
211214}
212215
213216fn merge_unique < Key , Item > (
214- a : impl IntoIterator < Item = ( Key , Item ) > ,
215- b : impl IntoIterator < Item = ( Key , Item ) > ,
216- ) -> IndexMap < Key , Item >
217+ mut a : IndexMap < Key , Item > ,
218+ b : IndexMap < Key , Item > ,
219+ ) -> Result < IndexMap < Key , Item > >
217220where
218221 Key : std:: fmt:: Debug + Eq + std:: hash:: Hash ,
222+ Item : PartialEq ,
219223{
220- let mut map = IndexMap :: new ( ) ;
221- for ( key, value) in a {
222- map. insert ( key, value) ;
223- }
224224 for ( key, value) in b {
225- match map . entry ( key) {
225+ match a . entry ( key) {
226226 indexmap:: map:: Entry :: Occupied ( entry) => {
227- #[ cfg( debug_assertions) ]
228- println ! ( "Entry is already occupied {:?}" , entry. key( ) ) ;
227+ if entry. get ( ) != & value {
228+ return Err ( Error :: unexpected ( format ! (
229+ "Duplicate key {:?} with different values" ,
230+ entry. key( )
231+ ) ) ) ;
232+ }
229233 }
230234 indexmap:: map:: Entry :: Vacant ( entry) => {
231235 entry. insert ( value) ;
232236 }
233237 }
234238 }
235- map
239+ Ok ( a )
236240}
0 commit comments