mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 17:11:30 +00:00
Draft smithy parser for AWS models
This commit is contained in:
@@ -0,0 +1,300 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
// Parse AWS Smithy models
|
||||
|
||||
type Smithy struct {
|
||||
Smithy string `json:"smithy"`
|
||||
Metadata map[string]interface{}
|
||||
Shapes map[string]interface{}
|
||||
}
|
||||
|
||||
type SmithyRange struct {
|
||||
Min int `json:"min"`
|
||||
Max int `json:"max"`
|
||||
}
|
||||
|
||||
type SmithyPaginated struct {
|
||||
InputToken string `json:"inputToken"`
|
||||
OutputToken string `json:"outputToken"`
|
||||
Items string `json:"items"`
|
||||
PageSize string `json:"pageSize"`
|
||||
}
|
||||
|
||||
type SmithyTrait struct {
|
||||
Documentation string `json:"smithy.api#documentation"`
|
||||
XMLName string `json:"smithy.api#xmlName"`
|
||||
Ec2QueryName string `json:"smithy.api#ec2QueryName"`
|
||||
|
||||
Range SmithyRange `json:"smithy.api#range"` // optional
|
||||
SmithyPaginated SmithyPaginated `json:"smithy.api#paginated"` // optional
|
||||
|
||||
}
|
||||
|
||||
type SmithyMember struct {
|
||||
Target string `json:"target"`
|
||||
Traits SmithyTrait `json:"traits"`
|
||||
}
|
||||
|
||||
type SmithyMemberStructure struct {
|
||||
Target string `json:"target"`
|
||||
Traits SmithyTrait `json:"traits"`
|
||||
}
|
||||
|
||||
type SmithyRequest struct {
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type SmithyRequestList struct {
|
||||
Type string `json:"type"`
|
||||
Member SmithyMember `json:"member"`
|
||||
}
|
||||
|
||||
type SmithyRequestStructure struct {
|
||||
Type string `json:"type"`
|
||||
Members map[string]SmithyMemberStructure `json:"members"`
|
||||
Traits SmithyTrait `json:"traits"`
|
||||
}
|
||||
|
||||
var result Smithy
|
||||
|
||||
var smithyTypes = map[string]string{
|
||||
"String": "string",
|
||||
"Integer": "int",
|
||||
"Boolean": "bool",
|
||||
"DateTime": "time.Time",
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
path := flag.String("path", "", "Path to the Smithy model")
|
||||
flag.Parse()
|
||||
|
||||
if path == nil {
|
||||
log.Fatal("path is required")
|
||||
}
|
||||
|
||||
// Open the file and read JSON
|
||||
jsonFile, err := os.Open(*path)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer jsonFile.Close()
|
||||
|
||||
// Read the file and unmarshal as JSON
|
||||
byteValue, _ := io.ReadAll(jsonFile)
|
||||
|
||||
json.Unmarshal([]byte(byteValue), &result)
|
||||
|
||||
// spew.Dump(result)
|
||||
|
||||
_, req := findShape("com.amazonaws.ec2#DescribeInstancesRequest")
|
||||
scanRequest("com.amazonaws.ec2#DescribeInstancesRequest", req, true)
|
||||
|
||||
/*
|
||||
for k, v := range result.Shapes {
|
||||
|
||||
// Find all request methods
|
||||
|
||||
// "com.amazonaws.ec2#RunInstancesRequest"
|
||||
// DescribeInstancesRequest
|
||||
if strings.HasSuffix(k, "DescribeInstancesRequest") {
|
||||
|
||||
//fmt.Println(k)
|
||||
|
||||
scanRequest(k, v.(interface{}), true)
|
||||
|
||||
// Loop in each request
|
||||
//for k2, v2 := range v.(map[string]interface{}) {
|
||||
// fmt.Println(k2, v2)
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
func scanRequest(key string, request interface{}, root bool) {
|
||||
|
||||
//spew.Dump(request)
|
||||
// Marshal into a SmithyRequest
|
||||
|
||||
// Unmarshal into a SmithyRequest
|
||||
|
||||
var smithyRequest SmithyRequest
|
||||
|
||||
b, _ := json.Marshal(request) // map -> JSON
|
||||
_ = json.Unmarshal(b, &smithyRequest) // JSON -> struct
|
||||
|
||||
//spew.Dump(smithyRequest)
|
||||
|
||||
keyName := strings.Split(key, "#")
|
||||
|
||||
if len(keyName) == 0 {
|
||||
fmt.Println("No key found")
|
||||
return
|
||||
}
|
||||
|
||||
if root {
|
||||
fmt.Printf("type %s struct {\n", keyName[1])
|
||||
}
|
||||
|
||||
if smithyRequest.Type == "structure" {
|
||||
findShapeRecursiveStructure(request)
|
||||
} else if smithyRequest.Type == "list" {
|
||||
findShapeRecursiveList(request)
|
||||
}
|
||||
|
||||
//fmt.Println(smithyRequest.Type)
|
||||
|
||||
//for k, v := range request {
|
||||
// fmt.Println(k, v)
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
func findShapeRecursiveList(request interface{}) error {
|
||||
|
||||
var smithyRequest SmithyRequestList
|
||||
|
||||
b, _ := json.Marshal(request) // map -> JSON
|
||||
_ = json.Unmarshal(b, &smithyRequest) // JSON -> struct
|
||||
|
||||
fmt.Println("findShapeRecursiveList:")
|
||||
spew.Dump(request)
|
||||
spew.Dump(smithyRequest)
|
||||
|
||||
memberType := strings.Split(smithyRequest.Member.Target, "#")
|
||||
|
||||
fmt.Println(memberType)
|
||||
|
||||
if len(memberType) == 0 {
|
||||
fmt.Println("No member type found")
|
||||
return nil
|
||||
}
|
||||
|
||||
typeName := memberType[1]
|
||||
|
||||
// If a matching smithyType
|
||||
goType := smithyTypes[typeName]
|
||||
|
||||
if goType != "" {
|
||||
fmt.Printf("%s %s `xml:\"%s\"`\n", goType, smithyRequest.Member.Traits.XMLName)
|
||||
|
||||
} else {
|
||||
//spew.Dump(v)
|
||||
fmt.Println("\t", smithyRequest.Member.Target, smithyRequest.Member.Traits.XMLName)
|
||||
|
||||
newSmithyRequest, request := findShape(smithyRequest.Member.Target)
|
||||
|
||||
if newSmithyRequest.Type == "structure" {
|
||||
findShapeRecursiveStructure(request)
|
||||
} else if newSmithyRequest.Type == "list" {
|
||||
findShapeRecursiveList(request)
|
||||
}
|
||||
|
||||
//findShapeRecursiveStructure(newSmithyRequest)
|
||||
|
||||
}
|
||||
|
||||
//fmt.Println(smithyRequest.Members)
|
||||
|
||||
fmt.Println()
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func findShapeRecursiveStructure(request interface{}) error {
|
||||
|
||||
fmt.Println("findShapeRecursiveStructure => \t")
|
||||
|
||||
var smithyRequest SmithyRequestStructure
|
||||
|
||||
b, _ := json.Marshal(request) // map -> JSON
|
||||
_ = json.Unmarshal(b, &smithyRequest) // JSON -> struct
|
||||
|
||||
for k, v := range smithyRequest.Members {
|
||||
|
||||
//fmt.Println("\t", k, v)
|
||||
|
||||
memberType := strings.Split(v.Target, "#")
|
||||
|
||||
fmt.Println(memberType)
|
||||
|
||||
if len(memberType) == 0 {
|
||||
fmt.Println("No member type found")
|
||||
continue
|
||||
}
|
||||
|
||||
typeName := memberType[1]
|
||||
|
||||
// If a matching smithyType
|
||||
goType := smithyTypes[typeName]
|
||||
|
||||
if goType != "" {
|
||||
fmt.Printf("%s %s `xml:\"%s\"`\n", k, goType, v.Traits.XMLName)
|
||||
|
||||
} else {
|
||||
//spew.Dump(v)
|
||||
//fmt.Println("\t", k, v.Target, v.Traits.XMLName)
|
||||
|
||||
newSmithyRequest, request := findShape(v.Target)
|
||||
|
||||
if newSmithyRequest.Type == "structure" {
|
||||
findShapeRecursiveStructure(request)
|
||||
} else if newSmithyRequest.Type == "list" {
|
||||
findShapeRecursiveList(request)
|
||||
}
|
||||
//findShapeRecursiveStructure(newSmithyRequest)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//fmt.Println(smithyRequest.Members)
|
||||
|
||||
fmt.Println()
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func findShape(key string) (SmithyRequest, interface{}) {
|
||||
|
||||
for k, v := range result.Shapes {
|
||||
if k == key {
|
||||
|
||||
//fmt.Println("MATCH", k, key)
|
||||
|
||||
//spew.Dump(v)
|
||||
//fmt.Println(k, v)
|
||||
var smithyRequest SmithyRequest
|
||||
|
||||
b, _ := json.Marshal(v) // map -> JSON
|
||||
_ = json.Unmarshal(b, &smithyRequest) // JSON -> struct
|
||||
|
||||
//spew.Dump(v)
|
||||
|
||||
//spew.Dump(smithyRequest)
|
||||
|
||||
return smithyRequest, v
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return SmithyRequest{}, nil
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user