Skip to content

Commit 6bf3697

Browse files
committed
encoding/openapi: support time types
Also recognize unsupported builtins for their type. Issue #56 Change-Id: Ic900829144d0130db412c1202f82df4e3a56c236 Reviewed-on: https://cue-review.googlesource.com/c/cue/+/2724 Reviewed-by: Marcel van Lohuizen <[email protected]>
1 parent 6cea136 commit 6bf3697

File tree

5 files changed

+93
-4
lines changed

5 files changed

+93
-4
lines changed

encoding/openapi/build.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ func (b *builder) value(v cue.Value, f typeFunc) (isRef bool) {
209209
count := 0
210210
disallowDefault := false
211211
var values cue.Value
212-
if b.ctx.expandRefs {
212+
if b.ctx.expandRefs || b.format != "" {
213213
// Cycles are not allowed when expanding references. Right now we just
214214
// cap the depth of evaluation at 30.
215215
// TODO: do something more principled.
@@ -760,7 +760,6 @@ func (b *builder) string(v cue.Value) {
760760
}
761761

762762
case cue.NoOp, cue.SelectorOp:
763-
// TODO: determine formats from specific types.
764763

765764
case cue.CallOp:
766765
name := fmt.Sprint(a[0])

encoding/openapi/openapi_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ func TestParseDefinitions(t *testing.T) {
6262
"nums.cue",
6363
"nums.json",
6464
defaultConfig,
65+
}, {
66+
"builtins.cue",
67+
"builtins.json",
68+
defaultConfig,
6569
}, {
6670
"oneof.cue",
6771
"oneof.json",
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import (
2+
"time"
3+
"list"
4+
)
5+
6+
_time = time
7+
8+
MyStruct: {
9+
timestamp1?: time.Time
10+
timestamp2?: time.Time()
11+
timestamp3?: time.Format(time.RFC3339Nano)
12+
timestamp4?: _time.Time
13+
date1?: time.Format(time.RFC3339Date)
14+
date2?: _time.Format(time.RFC3339Date)
15+
16+
// This is not an OpenAPI type and has no format. In this case
17+
// we map to a type so that it can be documented properly (without
18+
// repeating it).
19+
timeout?: time.Duration
20+
21+
contains: list.Contains("foo") // not supported, but should be recognized as list
22+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"openapi": "3.0.0",
3+
"info": {},
4+
"components": {
5+
"schemas": {
6+
"MyStruct": {
7+
"type": "object",
8+
"required": [
9+
"contains"
10+
],
11+
"properties": {
12+
"timestamp1": {
13+
"type": "string",
14+
"format": "dateTime"
15+
},
16+
"timestamp2": {
17+
"type": "string",
18+
"format": "dateTime"
19+
},
20+
"timestamp3": {
21+
"type": "string",
22+
"format": "dateTime"
23+
},
24+
"timestamp4": {
25+
"type": "string",
26+
"format": "dateTime"
27+
},
28+
"date1": {
29+
"type": "string",
30+
"format": "date"
31+
},
32+
"date2": {
33+
"type": "string",
34+
"format": "date"
35+
},
36+
"timeout": {
37+
"$ref": "#/components/schemas/Duration"
38+
},
39+
"contains": {
40+
"type": "array"
41+
}
42+
}
43+
},
44+
"Duration": {
45+
"description": "This is not an OpenAPI type and has no format. In this case\nwe map to a type so that it can be documented properly (without\nrepeating it).",
46+
"type": "string"
47+
}
48+
}
49+
}
50+
}

encoding/openapi/types.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
package openapi
1616

1717
import (
18+
"fmt"
19+
1820
"github.com/cockroachdb/apd/v2"
1921

2022
"cuelang.org/go/cue"
@@ -32,7 +34,15 @@ var cueToOpenAPI = map[string]string{
3234
"string": "string",
3335
"bytes": "binary",
3436

35-
// TODO: date, date-time, password.
37+
"time.Time": "dateTime",
38+
"time.Time ()": "dateTime",
39+
`time.Format ("2006-01-02")`: "date",
40+
41+
// TODO: if a format is more strict (e.g. using zeros instead of nines
42+
// for fractional seconds), we could still use this as an approximation.
43+
`time.Format ("2006-01-02T15:04:05.999999999Z07:00")`: "dateTime",
44+
45+
// TODO: password.
3646
}
3747

3848
func extractFormat(v cue.Value) string {
@@ -45,7 +55,11 @@ func extractFormat(v cue.Value) string {
4555
if err != nil {
4656
return ""
4757
}
48-
return cueToOpenAPI[string(b)]
58+
if s, ok := cueToOpenAPI[string(b)]; ok {
59+
return s
60+
}
61+
s := fmt.Sprint(v)
62+
return cueToOpenAPI[s]
4963
}
5064

5165
func simplify(b *builder, t *OrderedMap) {

0 commit comments

Comments
 (0)