Skip to content

Commit

Permalink
Merge pull request hashicorp#3407 from hashicorp/fromparse
Browse files Browse the repository at this point in the history
`tools/generator-go-sdk` - add FromParseResult on id generator
  • Loading branch information
tombuildsstuff authored Nov 27, 2023
2 parents 0dbebc2 + a110d30 commit c2d93e2
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 57 deletions.
71 changes: 44 additions & 27 deletions tools/generator-go-sdk/generator/templater_id_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ func (r resourceIdTemplater) methods() (*string, error) {
methods = append(methods, *functionBody)
}

functionBody, err = r.fromParseResultFunction(r.resource.Segments)
if err != nil {
return nil, fmt.Errorf("generating the fromParseResult function: %+v", err)
}
methods = append(methods, *functionBody)

// Validate function
methods = append(methods, r.validateFunction(nameWithoutSuffix))

Expand Down Expand Up @@ -264,9 +270,36 @@ func (r resourceIdTemplater) parseFunction(nameWithoutSuffix string, caseSensiti
functionName += "Insensitively"
}

description := fmt.Sprintf("// %[1]s parses 'input' into a %[2]s", functionName, r.name)
if !caseSensitive {
description = fmt.Sprintf(`
// %[1]s parses 'input' case-insensitively into a %[2]s
// note: this method should only be used for API response data and not user input`, functionName, r.name)
}

out := fmt.Sprintf(`%[4]s
func %[1]s(input string) (*%[2]s, error) {
parser := resourceids.NewParserFromResourceIdType(%[2]s{})
parsed, err := parser.Parse(input, %[3]t)
if err != nil {
return nil, fmt.Errorf("parsing %%q: %%+v", input, err)
}
id := %[2]s{}
if err := id.FromParseResult(*parsed); err != nil {
return nil, err
}
return &id, nil
}`, functionName, r.name, !caseSensitive, description)
return &out, nil
}

func (r resourceIdTemplater) fromParseResultFunction(segments []resourcemanager.ResourceIdSegment) (*string, error) {

lines := make([]string, 0)
varDeclaration := ""
for _, segment := range r.resource.Segments {
for _, segment := range segments {
switch segment.Type {
case resourcemanager.ConstantSegment:
{
Expand All @@ -276,14 +309,14 @@ func (r resourceIdTemplater) parseFunction(nameWithoutSuffix string, caseSensiti

lines = append(lines, fmt.Sprintf(`
if v, ok := parsed.Parsed[%[1]q]; true {
if v, ok := input.Parsed[%[1]q]; true {
if !ok {
return nil, resourceids.NewSegmentNotSpecifiedError(id, %[1]q, *parsed)
return resourceids.NewSegmentNotSpecifiedError(id, %[1]q, input)
}
%[1]s, err := parse%[3]s(v)
if err != nil {
return nil, fmt.Errorf("parsing %%q: %%+v", v, err)
return fmt.Errorf("parsing %%q: %%+v", v, err)
}
id.%[2]s = *%[1]s
}
Expand All @@ -294,8 +327,8 @@ func (r resourceIdTemplater) parseFunction(nameWithoutSuffix string, caseSensiti
case resourcemanager.ResourceGroupSegment, resourcemanager.ScopeSegment, resourcemanager.SubscriptionIdSegment, resourcemanager.UserSpecifiedSegment:
{
lines = append(lines, fmt.Sprintf(`
if id.%[2]s, ok = parsed.Parsed[%[1]q]; !ok {
return nil, resourceids.NewSegmentNotSpecifiedError(id, %[1]q, *parsed)
if id.%[2]s, ok = input.Parsed[%[1]q]; !ok {
return resourceids.NewSegmentNotSpecifiedError(id, %[1]q, input)
}
`, segment.Name, strings.Title(segment.Name)))

Expand All @@ -308,29 +341,13 @@ func (r resourceIdTemplater) parseFunction(nameWithoutSuffix string, caseSensiti
continue
}
}
out := fmt.Sprintf(`func (id *%[1]s) FromParseResult(input resourceids.ParseResult) error {
%[2]s
description := fmt.Sprintf("// %[1]s parses 'input' into a %[2]s", functionName, r.name)
if !caseSensitive {
description = fmt.Sprintf(`
// %[1]s parses 'input' case-insensitively into a %[2]s
// note: this method should only be used for API response data and not user input`, functionName, r.name)
}

out := fmt.Sprintf(`%[5]s
func %[1]s(input string) (*%[2]s, error) {
parser := resourceids.NewParserFromResourceIdType(%[2]s{})
parsed, err := parser.Parse(input, %[3]t)
if err != nil {
return nil, fmt.Errorf("parsing %%q: %%+v", input, err)
}
%[6]s
id := %[2]s{}
%[3]s
return nil
}`, r.name, varDeclaration, strings.Join(lines, "\n"))

%[4]s
return &id, nil
}`, functionName, r.name, !caseSensitive, strings.Join(lines, "\n"), description, varDeclaration)
return &out, nil
}

Expand Down
64 changes: 34 additions & 30 deletions tools/generator-go-sdk/generator/templater_id_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,10 @@ var _ resourceids.ResourceId = BasicTestId{}
return nil, fmt.Errorf("parsing %q: %+v", input, err)
}
var ok bool
id := BasicTestId{}
if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok {
return nil, resourceids.NewSegmentNotSpecifiedError(id, "subscriptionId", *parsed)
}
if err := id.FromParseResult(*parsed); err != nil {
return nil, err
}
return &id, nil
}
Expand All @@ -89,15 +88,24 @@ var _ resourceids.ResourceId = BasicTestId{}
return nil, fmt.Errorf("parsing %q: %+v", input, err)
}
var ok bool
id := BasicTestId{}
if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok {
return nil, resourceids.NewSegmentNotSpecifiedError(id, "subscriptionId", *parsed)
}
if err := id.FromParseResult(*parsed); err != nil {
return nil, err
}
return &id, nil
}
func (id *BasicTestId) FromParseResult(input resourceids.ParseResult) error {
var ok bool
if id.SubscriptionId, ok = input.Parsed["subscriptionId"]; !ok {
return resourceids.NewSegmentNotSpecifiedError(id, "subscriptionId", input)
}
return nil
}
// ValidateBasicTestID checks that 'input' can be parsed as a Basic Test ID
func ValidateBasicTestID(input interface{}, key string) (warnings []string, errors []error) {
v, ok := input.(string)
Expand Down Expand Up @@ -219,17 +227,8 @@ func ParseConstantOnlyID(input string) (*ConstantOnlyId, error) {
}
id := ConstantOnlyId{}
if v, ok := parsed.Parsed["thingId"]; true {
if !ok {
return nil, resourceids.NewSegmentNotSpecifiedError(id, "thingId", *parsed)
}
thingId, err := parseThing(v)
if err != nil {
return nil, fmt.Errorf("parsing %q: %+v", v, err)
}
id.ThingId = *thingId
if err := id.FromParseResult(*parsed); err != nil {
return nil, err
}
return &id, nil
Expand All @@ -245,22 +244,27 @@ func ParseConstantOnlyIDInsensitively(input string) (*ConstantOnlyId, error) {
}
id := ConstantOnlyId{}
if v, ok := parsed.Parsed["thingId"]; true {
if !ok {
return nil, resourceids.NewSegmentNotSpecifiedError(id, "thingId", *parsed)
}
thingId, err := parseThing(v)
if err != nil {
return nil, fmt.Errorf("parsing %q: %+v", v, err)
}
id.ThingId = *thingId
if err := id.FromParseResult(*parsed); err != nil {
return nil, err
}
return &id, nil
}
func (id *ConstantOnlyId) FromParseResult(input resourceids.ParseResult) error {
if v, ok := input.Parsed["thingId"]; true {
if !ok {
return resourceids.NewSegmentNotSpecifiedError(id, "thingId", input)
}
thingId, err := parseThing(v)
if err != nil {
return fmt.Errorf("parsing %q: %+v", v, err)
}
id.ThingId = *thingId
}
return nil
}
// ValidateConstantOnlyID checks that 'input' can be parsed as a Constant Only ID
func ValidateConstantOnlyID(input interface{}, key string) (warnings []string, errors []error) {
v, ok := input.(string)
Expand Down

0 comments on commit c2d93e2

Please sign in to comment.