1
1
use crate :: settings:: OpenApiSettings ;
2
2
use crate :: OperationInfo ;
3
3
use okapi:: openapi3:: * ;
4
- use okapi:: Map ;
5
4
use rocket:: http:: Method ;
6
5
use schemars:: gen:: SchemaGenerator ;
7
6
use schemars:: schema:: SchemaObject ;
8
7
use schemars:: JsonSchema ;
9
- use std:: collections:: { hash_map:: Entry as HashEntry , HashMap } ;
8
+ use schemars:: { Map , MapEntry } ;
9
+ use std:: collections:: HashMap ;
10
10
use std:: iter:: FromIterator ;
11
11
12
12
/// A struct that visits all `rocket::Route`s, and aggregates information about them.
13
13
#[ derive( Debug , Clone ) ]
14
14
pub struct OpenApiGenerator {
15
15
settings : OpenApiSettings ,
16
16
schema_generator : SchemaGenerator ,
17
- operations : HashMap < ( String , Method ) , Operation > ,
17
+ operations : Map < String , HashMap < Method , Operation > > ,
18
18
}
19
19
20
20
impl OpenApiGenerator {
@@ -33,15 +33,21 @@ impl OpenApiGenerator {
33
33
// TODO do this outside add_operation
34
34
op. operation . operation_id = Some ( op_id. trim_start_matches ( ':' ) . replace ( "::" , "_" ) ) ;
35
35
}
36
- match self . operations . entry ( ( op. path , op. method ) ) {
37
- HashEntry :: Occupied ( e) => {
38
- let ( path, method) = e. key ( ) ;
39
- panic ! (
40
- "An OpenAPI operation has already been added for {} {}" ,
41
- method, path
42
- ) ;
36
+ match self . operations . entry ( op. path ) {
37
+ MapEntry :: Occupied ( mut e) => {
38
+ let map = e. get_mut ( ) ;
39
+ if map. insert ( op. method , op. operation ) . is_some ( ) {
40
+ // This will trow a warning if 2 routes have the same path and method
41
+ // This is allowed by Rocket when a ranking is given for example: `#[get("/user", rank = 2)]`
42
+ // See: https://rocket.rs/v0.4/guide/requests/#forwarding
43
+ println ! ( "Warning: Operation replaced for {}:{}" , op. method, e. key( ) ) ;
44
+ }
45
+ }
46
+ MapEntry :: Vacant ( e) => {
47
+ let mut map = HashMap :: new ( ) ;
48
+ map. insert ( op. method , op. operation ) ;
49
+ e. insert ( map) ;
43
50
}
44
- HashEntry :: Vacant ( e) => e. insert ( op. operation ) ,
45
51
} ;
46
52
}
47
53
@@ -66,9 +72,11 @@ impl OpenApiGenerator {
66
72
openapi : "3.0.0" . to_owned ( ) ,
67
73
paths : {
68
74
let mut paths = Map :: new ( ) ;
69
- for ( ( path, method) , op) in self . operations {
70
- let path_item = paths. entry ( path) . or_default ( ) ;
71
- set_operation ( path_item, method, op) ;
75
+ for ( path, map) in self . operations {
76
+ for ( method, op) in map {
77
+ let path_item = paths. entry ( path. clone ( ) ) . or_default ( ) ;
78
+ set_operation ( path_item, method, op) ;
79
+ }
72
80
}
73
81
paths
74
82
} ,
0 commit comments