@@ -4,6 +4,7 @@ defmodule OpenApiSpex.PathItem do
4
4
"""
5
5
6
6
alias OpenApiSpex . { Operation , Server , Parameter , PathItem , Reference }
7
+
7
8
defstruct [
8
9
:"$ref" ,
9
10
:summary ,
@@ -29,31 +30,36 @@ defmodule OpenApiSpex.PathItem do
29
30
but they will not know which operations and parameters are available.
30
31
"""
31
32
@ type t :: % __MODULE__ {
32
- "$ref": String . t | nil ,
33
- summary: String . t | nil ,
34
- description: String . t | nil ,
35
- get: Operation . t | nil ,
36
- put: Operation . t | nil ,
37
- post: Operation . t | nil ,
38
- delete: Operation . t | nil ,
39
- options: Operation . t | nil ,
40
- head: Operation . t | nil ,
41
- patch: Operation . t | nil ,
42
- trace: Operation . t | nil ,
43
- servers: [ Server . t ] | nil ,
44
- parameters: [ Parameter . t | Reference . t ] | nil
45
- }
33
+ "$ref": String . t ( ) | nil ,
34
+ summary: String . t ( ) | nil ,
35
+ description: String . t ( ) | nil ,
36
+ get: Operation . t ( ) | nil ,
37
+ put: Operation . t ( ) | nil ,
38
+ post: Operation . t ( ) | nil ,
39
+ delete: Operation . t ( ) | nil ,
40
+ options: Operation . t ( ) | nil ,
41
+ head: Operation . t ( ) | nil ,
42
+ patch: Operation . t ( ) | nil ,
43
+ trace: Operation . t ( ) | nil ,
44
+ servers: [ Server . t ( ) ] | nil ,
45
+ parameters: [ Parameter . t ( ) | Reference . t ( ) ] | nil
46
+ }
46
47
47
48
@ typedoc """
48
49
Represents a route from in a Plug/Phoenix application.
49
50
Eg from the generated `__routes__` function in a Phoenix.Router module.
50
51
"""
51
- @ type route :: % { verb: atom , plug: atom , opts: any }
52
+ @ type route :: % {
53
+ required ( :verb ) => atom ,
54
+ required ( :plug ) => atom ,
55
+ optional ( :path ) => String . t ( ) ,
56
+ optional ( :opts ) => any
57
+ }
52
58
53
59
@ doc """
54
60
Builds a PathItem struct from a list of routes that share a path.
55
61
"""
56
- @ spec from_routes ( [ route ] ) :: nil | t
62
+ @ spec from_routes ( [ route ] ) :: { :ok , nil | t } | { :error , Sting . t ( ) }
57
63
def from_routes ( routes ) do
58
64
Enum . each ( routes , fn route ->
59
65
Code . ensure_loaded ( route . plug )
@@ -64,9 +70,22 @@ defmodule OpenApiSpex.PathItem do
64
70
|> from_valid_routes ( )
65
71
end
66
72
67
- @ spec from_valid_routes ( [ route ] ) :: nil | t
68
- defp from_valid_routes ( [ ] ) , do: nil
73
+ @ spec from_valid_routes ( [ route ] ) :: { :ok , nil | t } | { :error , String . t ( ) }
74
+ defp from_valid_routes ( [ ] ) , do: { :ok , nil }
75
+
69
76
defp from_valid_routes ( routes ) do
70
- struct ( PathItem , Enum . map ( routes , & { & 1 . verb , Operation . from_route ( & 1 ) } ) )
77
+ routes
78
+ |> Enum . map ( fn route -> { route . verb , Operation . from_route ( route ) } end )
79
+ |> Enum . reduce_while (
80
+ % PathItem { } ,
81
+ fn
82
+ { verb , { :ok , operation } } , acc -> { :cont , Map . put ( acc , verb , operation ) }
83
+ { _verb , { :error , reason } } , _acc -> { :halt , { :error , reason } }
84
+ end
85
+ )
86
+ |> case do
87
+ { :error , reason } -> { :error , reason }
88
+ path_item = % PathItem { } -> { :ok , path_item }
89
+ end
71
90
end
72
91
end
0 commit comments