1
0
mirror of https://github.com/rancher/steve.git synced 2025-09-20 11:00:25 +00:00

Make schema type definitions recursive.

This commit is contained in:
Chad Roberts
2025-01-24 11:25:34 -05:00
parent 809e927a0c
commit b03e41404c
2 changed files with 65 additions and 20 deletions

View File

@@ -20,23 +20,34 @@ func (s *schemaFieldVisitor) VisitArray(array *proto.Array) {
// it was kept this way to provide backwards compat with previous endpoints. // it was kept this way to provide backwards compat with previous endpoints.
array.SubType.Accept(s) array.SubType.Accept(s)
subField := s.field subField := s.field
field.Type = "array" field.Type = "array[" + subField.Type + "]"
field.SubType = subField.Type
s.field = field s.field = field
} }
// VisitMap turns a map into a definitionField (stored on the receiver). For maps of complex types, will also visit the // VisitMap turns a map into a definitionField (stored on the receiver). For maps of complex types, will also visit the
// subtype. // subtype.
//func (s *schemaFieldVisitor) VisitMap(protoMap *proto.Map) {
// field := definitionField{
// Description: protoMap.GetDescription(),
// }
// // this currently is not recursive and provides little information for nested types- while this isn't optimal,
// // it was kept this way to provide backwards compat with previous endpoints.
// protoMap.SubType.Accept(s)
// subField := s.field
// field.Type = "map[" + subField.Type + "]"
// s.field = field
//}
func (s *schemaFieldVisitor) VisitMap(protoMap *proto.Map) { func (s *schemaFieldVisitor) VisitMap(protoMap *proto.Map) {
field := definitionField{ field := definitionField{
Description: protoMap.GetDescription(), Description: protoMap.GetDescription(),
} }
// this currently is not recursive and provides little information for nested types- while this isn't optimal, // Recursively visit the value subtype
// it was kept this way to provide backwards compat with previous endpoints. subVisitor := &schemaFieldVisitor{definitions: s.definitions}
protoMap.SubType.Accept(s) protoMap.SubType.Accept(subVisitor)
subField := s.field subField := subVisitor.field
field.Type = "map" // Represent the map as "map[string]<value_type>"
field.SubType = subField.Type field.Type = "map[string]" + subField.Type
s.field = field s.field = field
} }

View File

@@ -72,6 +72,12 @@ var (
Description: "testArbitrary", Description: "testArbitrary",
}, },
} }
protoNestedMap = proto.Map{
BaseSchema: proto.BaseSchema{
Description: "nestedMap",
},
SubType: &protoKind,
}
) )
func TestSchemaFieldVisitor(t *testing.T) { func TestSchemaFieldVisitor(t *testing.T) {
@@ -87,9 +93,8 @@ func TestSchemaFieldVisitor(t *testing.T) {
inputSchema: &protoArray, inputSchema: &protoArray,
wantDefinitions: map[string]definition{}, wantDefinitions: map[string]definition{},
wantField: definitionField{ wantField: definitionField{
Type: "array", Type: "array[string]",
Description: protoArray.Description, Description: protoArray.Description,
SubType: protoPrimitive.Type,
}, },
}, },
{ {
@@ -97,9 +102,8 @@ func TestSchemaFieldVisitor(t *testing.T) {
inputSchema: &protoMap, inputSchema: &protoMap,
wantDefinitions: map[string]definition{}, wantDefinitions: map[string]definition{},
wantField: definitionField{ wantField: definitionField{
Type: "map", Type: "map[string]string",
Description: protoMap.Description, Description: protoMap.Description,
SubType: protoPrimitive.Type,
}, },
}, },
{ {
@@ -136,15 +140,13 @@ func TestSchemaFieldVisitor(t *testing.T) {
protoKind.Path.String(): { protoKind.Path.String(): {
ResourceFields: map[string]definitionField{ ResourceFields: map[string]definitionField{
"protoArray": { "protoArray": {
Type: "array", Type: "array[" + protoPrimitive.Type + "]",
Description: protoArray.Description, Description: protoArray.Description,
SubType: protoPrimitive.Type,
Required: true, Required: true,
}, },
"protoMap": { "protoMap": {
Type: "map", Type: "map[" + protoPrimitive.Type + "]string",
Description: protoMap.Description, Description: protoMap.Description,
SubType: protoPrimitive.Type,
}, },
"protoPrimitive": { "protoPrimitive": {
Type: protoPrimitive.Type, Type: protoPrimitive.Type,
@@ -181,15 +183,13 @@ func TestSchemaFieldVisitor(t *testing.T) {
protoKind.Path.String(): { protoKind.Path.String(): {
ResourceFields: map[string]definitionField{ ResourceFields: map[string]definitionField{
"protoArray": { "protoArray": {
Type: "array", Type: "array[string]",
Description: protoArray.Description, Description: protoArray.Description,
SubType: protoPrimitive.Type,
Required: true, Required: true,
}, },
"protoMap": { "protoMap": {
Type: "map", Type: "map[string]string",
Description: protoMap.Description, Description: protoMap.Description,
SubType: protoPrimitive.Type,
}, },
"protoPrimitive": { "protoPrimitive": {
Type: protoPrimitive.Type, Type: protoPrimitive.Type,
@@ -219,6 +219,40 @@ func TestSchemaFieldVisitor(t *testing.T) {
Description: protoArbitrary.Description, Description: protoArbitrary.Description,
}, },
}, },
{
name: "nested map with kind",
inputSchema: &protoNestedMap,
wantDefinitions: map[string]definition{
protoKind.Path.String(): {
ResourceFields: map[string]definitionField{
"protoArray": {
Type: "array[string]",
Description: protoArray.Description,
Required: true,
},
"protoMap": {
Type: "map[string]string",
Description: protoMap.Description,
},
"protoPrimitive": {
Type: protoPrimitive.Type,
Description: protoPrimitive.Description,
Required: true,
},
"protoRef": {
Type: protoKind.Path.String(),
Description: protoRef.Description,
},
},
Type: protoKind.Path.String(),
Description: protoKind.Description,
},
},
wantField: definitionField{
Type: "map[string]io.cattle.test",
Description: protoNestedMap.Description,
},
},
} }
for _, test := range tests { for _, test := range tests {