Skip to content

Commit

Permalink
Enhance simpleschema package to support nested complex types
Browse files Browse the repository at this point in the history
This commit significantly improves the `simpleschema` package ability to handle
complex, nested data structures. The `parseMapType` function has been refactored
to correctly parse nested map types and a new `findMatchingBracket` function has
been added to ensure robust bracket parsing. The Transformer.BuildOpenAPISchema
method has been restructured allowing for more flexible and accurate schema
generation for nested slices and maps.
  • Loading branch information
a-hilaly committed Sep 27, 2024
1 parent 343a43e commit b3bb62e
Show file tree
Hide file tree
Showing 5 changed files with 294 additions and 153 deletions.
45 changes: 39 additions & 6 deletions internal/typesystem/simpleschema/atomic.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,21 +80,54 @@ func isSliceType(s string) bool {

// parseMapType parses a map type string and returns the key and value types.
func parseMapType(s string) (string, string, error) {
// Remove the "map[" prefix and "]" suffix.
s = strings.TrimPrefix(s, "map[")
s = strings.TrimSuffix(s, "]")
parts := strings.Split(s, "]")
if len(parts) != 2 {
if !strings.HasPrefix(s, "map[") {
return "", "", fmt.Errorf("invalid map type: %s", s)
}
return parts[0], parts[1], nil

// remove the "map[" prefix
s = s[4:]

keyEndIndex := findMatchingBracket(s)
if keyEndIndex == -1 {
return "", "", fmt.Errorf("invalid map key type: %s", s)
}

keyType := s[:keyEndIndex]
valueType := s[keyEndIndex+1:]

valueType = strings.TrimSuffix(valueType, "]")
if keyType == "" {
return "", "", fmt.Errorf("empty map key type")
}
if valueType == "" {
return "", "", fmt.Errorf("empty map value type")
}

return keyType, valueType, nil
}
func findMatchingBracket(s string) int {
depth := 1
for i, char := range s {
switch char {
case '[':
depth++
case ']':
depth--
if depth == 0 {
return i
}
}
}
// no matching bracket found
return -1
}

// parseSliceType parses a slice type string and returns the element type.
func parseSliceType(s string) (string, error) {
if !strings.HasPrefix(s, "[]") {
return "", fmt.Errorf("invalid slice type: %s", s)
}

// Remove the "[]" prefix.
s = strings.TrimPrefix(s, "[]")
if s == "" {
Expand Down
9 changes: 5 additions & 4 deletions internal/typesystem/simpleschema/atomic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,9 @@ func TestParseMapType(t *testing.T) {
wantErr bool
}{
{"valid map", "map[string]integer", "string", "integer", false},
// not supported yet... do we need to support this?
// {"Valid Complex Map", "map[string]map[int]bool", "string", "map[int]bool", false},
{"Valid Complex Map", "map[string]map[int]bool", "string", "map[int]bool", false},
{"Nested Map", "map[string]map[string]map[string]integer", "string", "map[string]map[string]integer", false},
{"invalid map", "map[]", "", "", true},
{"invalid map", "map[string]", "", "", true},
{"not a map", "something", "", "", true},
}
Expand Down Expand Up @@ -143,8 +144,8 @@ func TestParseSliceType(t *testing.T) {
wantErr bool
}{
{"valid slice", "[]string", "string", false},
// not supported yet
// {"Valid Complex Slice", "[]map[string]int", "map[string]int", false},
{"Valid Complex Slice", "[]map[string]int", "map[string]int", false},
{"Nested Slice", "[][][]int", "[][]int", false},
{"invalid slice", "[]", "", true},
{"Not a slice", "string", "", true},
}
Expand Down
3 changes: 2 additions & 1 deletion internal/typesystem/simpleschema/field_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ func TestParseFieldSchema(t *testing.T) {
wantType: "string",
wantMarkers: []*Marker{
{MarkerType: MarkerTypeRequired, Key: "required", Value: "true"},
{MarkerType: MarkerTypeDescription, Key: "description", Value: "A test field"},
{MarkerType: MarkerTypeDescription, Key: "description", Value: "A-test-field"},
{MarkerType: MarkerTypeDefault, Key: "default", Value: "kubernetes-is-very-nice!"},
},
wantErr: false,
},
Expand Down
Loading

0 comments on commit b3bb62e

Please sign in to comment.