Skip to content

Commit 56c9c13

Browse files
committed
feat(codegen): emit nullable.Value[T] when nullable-type is enabled
- Switch generator to output nullable.Value[T] for nullable fields - Update schema tests to expect Value[T] - Update README to prefer nullable.Value with migration notes - Do not edit generated fixtures; regeneration will follow after library update Notes: - Requires nullable library release containing Value[T] - Regenerate test fixtures after bumping dependency Refs: oapi-codegen/nullable#21 Pending: oapi-codegen/nullable#21
1 parent bdc4edc commit 56c9c13

File tree

6 files changed

+19
-16
lines changed

6 files changed

+19
-16
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2327,7 +2327,7 @@ However, you lose the ability to understand the three cases, as there's no way t
23272327
- is this field `null`? (Can be checked with `S.Field == nil`)
23282328
- does this field have a value? (`S.Field != nil && *S.Field == "123"`)
23292329

2330-
As of `oapi-codegen` [v2.1.0](https://github.com/oapi-codegen/oapi-codegen/releases/tag/v2.1.0) it is now possible to represent this with the `nullable.Nullable` type from [our new library, oapi-codegen/nullable](https://github.com/oapi-codegen/nullable).
2330+
As of `oapi-codegen` [v2.1.0](https://github.com/oapi-codegen/oapi-codegen/releases/tag/v2.1.0) it is now possible to represent this with the `nullable.Value` type from [our library, oapi-codegen/nullable](https://github.com/oapi-codegen/nullable). (previously `nullable.Nullable`, now deprecated);
23312331

23322332
If you configure your generator's Output Options to opt-in to this behaviour, as so:
23332333

@@ -2341,7 +2341,7 @@ You will now receive the following output:
23412341
```go
23422342
type S struct {
23432343
// note that there's no pointer here, just `omitempty`
2344-
Field nullable.Nullable[string] `json:"field,omitempty"`
2344+
Field nullable.Value[string] `json:"field,omitempty"`
23452345
}
23462346
```
23472347

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ require (
2121
github.com/josharian/intern v1.0.0 // indirect
2222
github.com/mailru/easyjson v0.7.7 // indirect
2323
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
24+
github.com/oapi-codegen/nullable v1.1.0 // indirect
2425
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect
2526
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect
2627
github.com/perimeterx/marshmallow v1.1.5 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwd
5151
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
5252
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
5353
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
54+
github.com/oapi-codegen/nullable v1.1.0 h1:eAh8JVc5430VtYVnq00Hrbpag9PFRGWLjxR1/3KntMs=
55+
github.com/oapi-codegen/nullable v1.1.0/go.mod h1:KUZ3vUzkmEKY90ksAmit2+5juDIhIZhfDl+0PwOQlFY=
5456
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY=
5557
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw=
5658
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c=

internal/test/issues/issue-1039/issue_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ func ptr[T any](v T) *T {
1717
func TestNullableTypesMarshal(t *testing.T) {
1818
// include all fields in patch request
1919
patchReq := PatchRequest{
20-
ComplexRequiredNullable: nullable.NewNullableWithValue(ComplexRequiredNullable{
20+
ComplexRequiredNullable: nullable.NewValue(ComplexRequiredNullable{
2121
Name: ptr("test-name"),
2222
}),
2323
SimpleOptionalNonNullable: ptr(SimpleOptionalNonNullable("bar")),
24-
ComplexOptionalNullable: nullable.NewNullableWithValue(ComplexOptionalNullable{
25-
AliasName: nullable.NewNullableWithValue("foo-alias"),
24+
ComplexOptionalNullable: nullable.NewValue(ComplexOptionalNullable{
25+
AliasName: nullable.NewValue("foo-alias"),
2626
Name: ptr("foo"),
2727
}),
28-
SimpleOptionalNullable: nullable.NewNullableWithValue(10),
29-
SimpleRequiredNullable: nullable.NewNullableWithValue(5),
28+
SimpleOptionalNullable: nullable.NewValue(10),
29+
SimpleRequiredNullable: nullable.NewValue(5),
3030
}
3131

3232
expected := []byte(`{"complex_optional_nullable":{"alias_name":"foo-alias","name":"foo"},"complex_required_nullable":{"name":"test-name"},"simple_optional_non_nullable":"bar","simple_optional_nullable":10,"simple_required_nullable":5}`)
@@ -37,15 +37,15 @@ func TestNullableTypesMarshal(t *testing.T) {
3737

3838
// omit some fields
3939
patchReq = PatchRequest{
40-
ComplexRequiredNullable: nullable.NewNullableWithValue(ComplexRequiredNullable{
40+
ComplexRequiredNullable: nullable.NewValue(ComplexRequiredNullable{
4141
Name: ptr("test-name"),
4242
}),
4343
// SimpleOptionalNonNullable is omitted
44-
ComplexOptionalNullable: nullable.NewNullableWithValue(ComplexOptionalNullable{
45-
AliasName: nullable.NewNullableWithValue("test-alias-name"),
44+
ComplexOptionalNullable: nullable.NewValue(ComplexOptionalNullable{
45+
AliasName: nullable.NewValue("test-alias-name"),
4646
Name: ptr("test-name"),
4747
}),
48-
SimpleOptionalNullable: nullable.NewNullableWithValue(10),
48+
SimpleOptionalNullable: nullable.NewValue(10),
4949
// SimpleRequiredNullable is omitted
5050
}
5151

pkg/codegen/schema.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ func (p Property) GoFieldName() string {
116116
func (p Property) GoTypeDef() string {
117117
typeDef := p.Schema.TypeDecl()
118118
if globalState.options.OutputOptions.NullableType && p.Nullable {
119-
return "nullable.Nullable[" + typeDef + "]"
119+
return "nullable.Value[" + typeDef + "]"
120120
}
121121
if !p.Schema.SkipOptionalPointer &&
122122
(!p.Required || p.Nullable ||

pkg/codegen/schema_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ func TestProperty_GoTypeDef_nullable(t *testing.T) {
308308
Required: true,
309309
Nullable: true,
310310
},
311-
want: "nullable.Nullable[int]",
311+
want: "nullable.Value[int]",
312312
},
313313

314314
{
@@ -336,7 +336,7 @@ func TestProperty_GoTypeDef_nullable(t *testing.T) {
336336
Required: false,
337337
Nullable: true,
338338
},
339-
want: "nullable.Nullable[int]",
339+
want: "nullable.Value[int]",
340340
},
341341

342342
{
@@ -422,7 +422,7 @@ func TestProperty_GoTypeDef_nullable(t *testing.T) {
422422
WriteOnly: true,
423423
Nullable: true,
424424
},
425-
want: "nullable.Nullable[int]",
425+
want: "nullable.Value[int]",
426426
},
427427

428428
{
@@ -436,7 +436,7 @@ func TestProperty_GoTypeDef_nullable(t *testing.T) {
436436
WriteOnly: true,
437437
Nullable: true,
438438
},
439-
want: "nullable.Nullable[int]",
439+
want: "nullable.Value[int]",
440440
},
441441
}
442442
for _, tt := range tests {

0 commit comments

Comments
 (0)