Skip to content

Commit 50f3922

Browse files
committed
refactor(ogenreflect): rename Operation to RuntimeOperation
1 parent 99c6059 commit 50f3922

File tree

6 files changed

+127
-72
lines changed

6 files changed

+127
-72
lines changed

gen/_template/ogenreflect.tmpl

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ type api struct {
3333
{{ with $ops := $.Operations }}
3434
type paths struct {
3535
{{- range $op := $ops }}
36-
{{ $op.Name }} ogenreflect.Operation
36+
{{ $op.Name }} ogenreflect.RuntimeOperation
3737
{{- end }}
3838
}
3939

@@ -42,7 +42,7 @@ func getPaths() paths {
4242
}
4343

4444
// FindByName finds operation by ogen name.
45-
func (p paths) FindByName(name string) (op ogenreflect.Operation, _ bool) {
45+
func (p paths) FindByName(name string) (op ogenreflect.RuntimeOperation, _ bool) {
4646
switch name {
4747
{{- range $op := $ops }}
4848
case {{ quote $op.Name }}:
@@ -54,7 +54,7 @@ func (p paths) FindByName(name string) (op ogenreflect.Operation, _ bool) {
5454
}
5555

5656
// FindByOperationID finds operation by operationId.
57-
func (p paths) FindByOperationID(operationID string) (op ogenreflect.Operation, _ bool) {
57+
func (p paths) FindByOperationID(operationID string) (op ogenreflect.RuntimeOperation, _ bool) {
5858
switch operationID {
5959
{{- range $op := $ops }}{{- with $id := $op.Spec.OperationID }}
6060
case {{ quote $id }}:
@@ -69,7 +69,7 @@ func (p paths) FindByOperationID(operationID string) (op ogenreflect.Operation,
6969
{{ with $ops := $.Webhooks }}
7070
type webhooks struct {
7171
{{- range $op := $ops }}
72-
{{ $op.Name }} ogenreflect.Operation
72+
{{ $op.Name }} ogenreflect.RuntimeOperation
7373
{{- end }}
7474
}
7575

@@ -78,7 +78,7 @@ func getWebhooks() webhooks {
7878
}
7979

8080
// FindByName finds operation by ogen name.
81-
func (w webhooks) FindByName(name string) (op ogenreflect.Operation, _ bool) {
81+
func (w webhooks) FindByName(name string) (op ogenreflect.RuntimeOperation, _ bool) {
8282
switch name {
8383
{{- range $op := $ops }}
8484
case {{ quote $op.Name }}:
@@ -90,7 +90,7 @@ func (w webhooks) FindByName(name string) (op ogenreflect.Operation, _ bool) {
9090
}
9191

9292
// FindByOperationID finds operation by operationId.
93-
func (w webhooks) FindByOperationID(operationID string) (op ogenreflect.Operation, _ bool) {
93+
func (w webhooks) FindByOperationID(operationID string) (op ogenreflect.RuntimeOperation, _ bool) {
9494
switch operationID {
9595
{{- range $op := $ops }}{{- with $id := $op.Spec.OperationID }}
9696
case {{ quote $id }}:
@@ -106,7 +106,7 @@ func (w webhooks) FindByOperationID(operationID string) (op ogenreflect.Operatio
106106

107107
{{ define "ogenreflect/operation" -}}
108108
{{- /*gotype: github.com/ogen-go/ogen/gen/ir.Operation*/ -}}{{ $op := $ -}}
109-
ogenreflect.Operation{
109+
ogenreflect.RuntimeOperation{
110110
Name: {{ quote $op.Name }},
111111
ID: {{ quote $op.Spec.OperationID }},
112112
Types: ogenreflect.OperationTypes{
@@ -129,21 +129,20 @@ ogenreflect.Operation{
129129
},
130130
{{- end }}
131131
{{- with $p := $op.Params }}
132-
Params: ogenreflect.ParameterMap[ogenreflect.ParameterType]{
132+
Params: ogenreflect.ParametersType{
133+
StructType: reflect.TypeOf(new({{ $op.Name }}Params)).Elem(),
134+
Map: ogenreflect.ParameterMap[ogenreflect.ParameterType]{
133135
{{- range $param := $p }}
134-
{Name: {{ quote $param.Spec.Name }}, In: {{ quote $param.Spec.In }}}: {
135-
Type: reflect.TypeOf(new({{ $param.Type.Go }})).Elem(),
136-
Name: {{ quote $param.Spec.Name }},
137-
In: {{ quote $param.Spec.In }},
138-
Style: {{ quote $param.Spec.Style }},
139-
Explode: {{ $param.Spec.Explode }},
140-
Required: {{ $param.Spec.Required }},
141-
},
136+
{
137+
Name: {{ quote $param.Spec.Name }},
138+
In: {{ quote $param.Spec.In }},
139+
}: {{ template "ogenreflect/parameter" $param -}},
142140
{{- end }}
141+
},
143142
},
144143
{{- end }}
145144
{{- with $resp := $op.Responses }}
146-
Response: ogenreflect.ResponseType{
145+
Responses: ogenreflect.ResponsesType{
147146
Type: reflect.TypeOf(new({{ $resp.Type.Go }})).Elem(),
148147
{{- if not $resp.Type.IsInterface }}
149148
Implementations: nil,
@@ -154,15 +153,15 @@ ogenreflect.Operation{
154153
{{- end }}
155154
},
156155
{{- end }}
157-
PatternMap: map[string]ogenreflect.Contents{
156+
PatternMap: map[string]ogenreflect.ResponseType{
158157
{{- range $code, $resp := $resp.StatusCode }}
159-
{{ print $code | quote }}: {{ template "ogenreflect/contents" $resp.Contents -}},
158+
{{ print $code | quote }}: {{ template "ogenreflect/response" $resp -}},
160159
{{- end }}
161160
{{- range $idx, $resp := $resp.Pattern }}{{- if $resp }}
162-
{{ printf "%dXX" (add $idx 1) | quote }}: {{ template "ogenreflect/contents" $resp.Contents -}},
161+
{{ printf "%dXX" (add $idx 1) | quote }}: {{ template "ogenreflect/response" $resp -}},
163162
{{- end }}{{- end }}
164163
{{- with $resp := $resp.Default }}
165-
"default": {{ template "ogenreflect/contents" $resp.Contents -}},
164+
"default": {{ template "ogenreflect/response" $resp -}},
166165
{{- end }}
167166
},
168167
},
@@ -171,6 +170,30 @@ ogenreflect.Operation{
171170
}
172171
{{- end }}
173172

173+
{{ define "ogenreflect/response" -}}
174+
{{- /*gotype: github.com/ogen-go/ogen/gen/ir.Response*/ -}}{{ $resp := $ -}}
175+
ogenreflect.ResponseType{
176+
Headers: map[string]ogenreflect.ParameterType{
177+
{{- range $header := $resp.Headers }}
178+
{{ quote $header.Spec.Name }}: {{ template "ogenreflect/parameter" $header -}},
179+
{{- end }}
180+
},
181+
Contents: {{ template "ogenreflect/contents" $resp.Contents -}},
182+
}
183+
{{- end }}
184+
185+
{{ define "ogenreflect/parameter" -}}
186+
{{- /*gotype: github.com/ogen-go/ogen/gen/ir.Parameter*/ -}}{{ $param := $ -}}
187+
ogenreflect.ParameterType{
188+
Type: reflect.TypeOf(new({{ $param.Type.Go }})).Elem(),
189+
Name: {{ quote $param.Spec.Name }},
190+
In: {{ quote $param.Spec.In }},
191+
Style: {{ quote $param.Spec.Style }},
192+
Explode: {{ $param.Spec.Explode }},
193+
Required: {{ $param.Spec.Required }},
194+
}
195+
{{- end }}
196+
174197
{{ define "ogenreflect/contents" -}}
175198
ogenreflect.Contents{
176199
{{- range $ct, $media := $ }}

middleware/middleware.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ type Request struct {
2727
// Deprecated: use Op instead.
2828
OperationID string
2929
// Op contains the operation information.
30-
Op ogenreflect.Operation
30+
Op ogenreflect.RuntimeOperation
3131
// Body is the operation request body. May be nil, if the operation has not body.
3232
Body any
3333
// Params is the operation parameters.

ogenerrors/ogenerrors.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type Error interface {
2121
// Deprecated: use Op instead.
2222
OperationID() string
2323
// Op returns operation info.
24-
Op() ogenreflect.Operation
24+
Op() ogenreflect.RuntimeOperation
2525
// Code returns HTTP code to respond.
2626
Code() int
2727

@@ -48,11 +48,11 @@ type OperationContext struct {
4848
// Deprecated: use Operation instead.
4949
ID string
5050
// Operation defines operation info.
51-
Operation ogenreflect.Operation
51+
Operation ogenreflect.RuntimeOperation
5252
}
5353

5454
// Op returns operation info.
55-
func (d OperationContext) Op() ogenreflect.Operation {
55+
func (d OperationContext) Op() ogenreflect.RuntimeOperation {
5656
return d.Operation
5757
}
5858

File renamed without changes.

ogenreflect/operation.go renamed to ogenreflect/runtime_operation.go

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import (
55
"strconv"
66
)
77

8-
// Operation stores the operation information.
9-
type Operation struct {
8+
// RuntimeOperation stores the operation information.
9+
type RuntimeOperation struct {
1010
// Name is the ogen operation name. It is guaranteed to be unique and not empty.
1111
Name string
1212
// ID is the spec operation ID, if any.
@@ -19,10 +19,10 @@ type Operation struct {
1919
type OperationTypes struct {
2020
// Request is the operation request type.
2121
Request RequestType
22-
// Params stores the operation parameters types by name.
23-
Params ParameterMap[ParameterType]
24-
// Response is the operation response type.
25-
Response ResponseType
22+
// Params stores the operation parameters types.
23+
Params ParametersType
24+
// Responses stores the operation responses types.
25+
Responses ResponsesType
2626
}
2727

2828
// IsRequest checks if the type is the operation request type.
@@ -45,7 +45,7 @@ func (t OperationTypes) IsRequest(v any) bool {
4545

4646
// IsParam checks if the type is the operation param type.
4747
func (t OperationTypes) IsParam(v any) bool {
48-
for _, impl := range t.Params {
48+
for _, impl := range t.Params.Map {
4949
if reflect.TypeOf(v) == impl.Type {
5050
return true
5151
}
@@ -55,7 +55,7 @@ func (t OperationTypes) IsParam(v any) bool {
5555

5656
// IsResponse checks if the type is the operation response type.
5757
func (t OperationTypes) IsResponse(v any) bool {
58-
r := t.Response
58+
r := t.Responses
5959
if len(r.Implementations) == 0 {
6060
return reflect.TypeOf(v) == r.Type
6161
}
@@ -100,8 +100,18 @@ type ParameterType struct {
100100
Required bool
101101
}
102102

103-
// ResponseType holds the response type information.
104-
type ResponseType struct {
103+
// ParametersType holds the parameters type information.
104+
type ParametersType struct {
105+
// StructType is the parameters struct type.
106+
//
107+
// StructType is nil if the operation has no parameters.
108+
StructType reflect.Type
109+
// Map stores the operation parameters types.
110+
Map ParameterMap[ParameterType]
111+
}
112+
113+
// ResponsesType holds the response type information.
114+
type ResponsesType struct {
105115
// Type is the response type.
106116
//
107117
// If operation defines multiple content types, Type is the interface type, implemented
@@ -114,32 +124,43 @@ type ResponseType struct {
114124
// PatternMap stores the response contents by pattern.
115125
//
116126
// If element is empty, the response has no content for the pattern.
117-
PatternMap map[string]Contents
127+
PatternMap map[string]ResponseType
118128
}
119129

120-
// FindContents returns the matching contents for the given status code.
121-
func (r ResponseType) FindContents(code int) (Contents, bool) {
122-
c, ok := r.PatternMap[strconv.Itoa(code)]
130+
// FindResponse returns the matching contents for the given status code.
131+
func (r ResponsesType) FindResponse(code int) (rt ResponseType, ok bool) {
132+
if code < 100 || code > 599 {
133+
return rt, false
134+
}
135+
rt, ok = r.PatternMap[strconv.Itoa(code)]
123136
if ok {
124-
return c, true
137+
return rt, true
125138
}
126139
switch code / 100 {
127140
case 1:
128-
c, ok = r.PatternMap["1XX"]
141+
rt, ok = r.PatternMap["1XX"]
129142
case 2:
130-
c, ok = r.PatternMap["2XX"]
143+
rt, ok = r.PatternMap["2XX"]
131144
case 3:
132-
c, ok = r.PatternMap["3XX"]
145+
rt, ok = r.PatternMap["3XX"]
133146
case 4:
134-
c, ok = r.PatternMap["4XX"]
147+
rt, ok = r.PatternMap["4XX"]
135148
case 5:
136-
c, ok = r.PatternMap["5XX"]
149+
rt, ok = r.PatternMap["5XX"]
137150
}
138151
if ok {
139-
return c, true
152+
return rt, true
140153
}
141-
c, ok = r.PatternMap["default"]
142-
return c, ok
154+
rt, ok = r.PatternMap["default"]
155+
return rt, ok
156+
}
157+
158+
// ResponseType is the response type.
159+
type ResponseType struct {
160+
// Headers stores the response headers.
161+
Headers map[string]ParameterType
162+
// Contents stores the response contents.
163+
Contents Contents
143164
}
144165

145166
// Contents is the request or response contents.

ogenreflect/operation_test.go renamed to ogenreflect/runtime_operation_test.go

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func TestOperationTypes(t *testing.T) {
6060
a := require.New(t)
6161

6262
ot := OperationTypes{
63-
Response: ResponseType{
63+
Responses: ResponsesType{
6464
Type: tt.typ,
6565
Implementations: tt.impl,
6666
},
@@ -75,12 +75,14 @@ func TestOperationTypes(t *testing.T) {
7575
})
7676
t.Run("IsParam", func(t *testing.T) {
7777
ot := OperationTypes{
78-
Params: ParameterMap[ParameterType]{
79-
{"cache", "query"}: {
80-
Type: typBool,
81-
},
82-
{"id", "path"}: {
83-
Type: typInt64,
78+
Params: ParametersType{
79+
Map: ParameterMap[ParameterType]{
80+
{"cache", "query"}: {
81+
Type: typBool,
82+
},
83+
{"id", "path"}: {
84+
Type: typInt64,
85+
},
8486
},
8587
},
8688
}
@@ -93,43 +95,52 @@ func TestOperationTypes(t *testing.T) {
9395
})
9496
}
9597

96-
func TestResponseType_FindContents(t *testing.T) {
97-
a := Contents{"application/json": nil}
98-
b := Contents{"text/html": nil}
99-
c := Contents{}
98+
func TestResponseType_FindResponse(t *testing.T) {
99+
a := ResponseType{
100+
Contents: Contents{
101+
"application/json": nil,
102+
},
103+
}
104+
b := ResponseType{
105+
Contents: Contents{
106+
"text/html": nil,
107+
},
108+
}
109+
c := ResponseType{}
100110

101111
tests := []struct {
102-
patterns map[string]Contents
112+
patterns map[string]ResponseType
103113
code int
104-
want Contents
114+
want ResponseType
105115
wantOk bool
106116
}{
107117
// Exact match.
108-
{map[string]Contents{"200": a}, 200, a, true},
109-
{map[string]Contents{"200": a, "201": b}, 200, a, true},
118+
{map[string]ResponseType{"200": a}, 200, a, true},
119+
{map[string]ResponseType{"200": a, "201": b}, 200, a, true},
110120

111121
// Pattern.
112-
{map[string]Contents{"2XX": a}, 200, a, true},
113-
{map[string]Contents{"2XX": a}, 201, a, true},
122+
{map[string]ResponseType{"2XX": a}, 200, a, true},
123+
{map[string]ResponseType{"2XX": a}, 201, a, true},
114124

115125
// Combined.
116-
{map[string]Contents{"200": a, "2XX": b, "default": c}, 200, a, true},
117-
{map[string]Contents{"200": a, "2XX": b, "default": c}, 201, b, true},
118-
{map[string]Contents{"200": a, "2XX": b, "default": c}, 500, c, true},
126+
{map[string]ResponseType{"200": a, "2XX": b, "default": c}, 200, a, true},
127+
{map[string]ResponseType{"200": a, "2XX": b, "default": c}, 201, b, true},
128+
{map[string]ResponseType{"200": a, "2XX": b, "default": c}, 500, c, true},
119129

120130
// No match.
121-
{nil, 0, nil, false},
122-
{map[string]Contents{"200": a}, 201, nil, false},
131+
{nil, 0, ResponseType{}, false},
132+
{nil, 200, ResponseType{}, false},
133+
{map[string]ResponseType{"200": a}, 201, ResponseType{}, false},
123134
}
124135
for i, tt := range tests {
125136
tt := tt
126137
t.Run(fmt.Sprintf("Test%d", i+1), func(t *testing.T) {
127138
a := require.New(t)
128139

129-
rtyp := ResponseType{
140+
rtyp := ResponsesType{
130141
PatternMap: tt.patterns,
131142
}
132-
got, gotOk := rtyp.FindContents(tt.code)
143+
got, gotOk := rtyp.FindResponse(tt.code)
133144
if !tt.wantOk {
134145
a.False(gotOk)
135146
return

0 commit comments

Comments
 (0)