From f1c430482c11e1df7eb0f8988b9617ab47d84b41 Mon Sep 17 00:00:00 2001 From: Mitchell Stanton Date: Wed, 4 Sep 2024 23:55:54 -0400 Subject: [PATCH] mv builder funcs --- build-struct.go | 156 +++--------------------------------------------- 1 file changed, 8 insertions(+), 148 deletions(-) diff --git a/build-struct.go b/build-struct.go index fa15582..4237704 100644 --- a/build-struct.go +++ b/build-struct.go @@ -8,35 +8,10 @@ Usage: package main import ( - "encoding/json" "fmt" - "math" "os" - "strings" - "gopkg.in/yaml.v2" -) - -// Static variables -var ( - // Variable for the file type - JSON - ftJSON = "json" - // Variable for the file type - YAML - ftYAML = "yaml" -) - -// Dynamic variables -var ( - // structName is the name of the struct - structName string - // The path to the file - filePath string - // The file type of the provided file (JSON or YAML) - fileType string - // The data from the file - mappedFileData map[interface{}]interface{} - // structOutput is the output of the struct - structOutput string + "github.com/mitchs-dev/build-struct/pkg/builder" ) func init() { @@ -48,25 +23,25 @@ func init() { } // Set the struct name - structName = os.Args[1] + builder.StructName = os.Args[1] // Set the file path - filePath = os.Args[2] + builder.FilePath = os.Args[2] // Make sure that the file exists - if _, err := os.Stat(filePath); os.IsNotExist(err) { + if _, err := os.Stat(builder.FilePath); os.IsNotExist(err) { fmt.Println("Error: The provided file does not exist.") os.Exit(1) } // Make sure that the file is not empty - if _, err := os.Stat(filePath); os.IsNotExist(err) { + if _, err := os.Stat(builder.FilePath); os.IsNotExist(err) { fmt.Println("Error: The file is empty.") os.Exit(1) } // Make sure that it's a file and not a directory - if fileInfo, err := os.Stat(filePath); err == nil && fileInfo.IsDir() { + if fileInfo, err := os.Stat(builder.FilePath); err == nil && fileInfo.IsDir() { fmt.Println("Error: The provided path is a directory.") os.Exit(1) } @@ -75,8 +50,8 @@ func init() { func main() { - determineFileType() - structOutput := buildStructFromData() + builder.DetermineFileType() + structOutput := builder.BuildStructFromData() // Return the struct output if it was built successfully if structOutput != "" { @@ -88,118 +63,3 @@ func main() { } } - -// determineFileType determines the file type of the provided file -func determineFileType() { - // Read the file - fileData, err := os.ReadFile(filePath) - if err != nil { - fmt.Println("Error: Could not read the file.") - os.Exit(1) - } - - // Try to unmarshal the data into a map[interface{}]interface{} - var data map[interface{}]interface{} - jsonErr := json.Unmarshal(fileData, &data) - yamlErr := yaml.Unmarshal(fileData, &data) - - // If JSON unmarshalling was successful, set the file type to JSON - if jsonErr == nil { - fileType = ftJSON - mappedFileData = data - return - } - - // If YAML unmarshalling was successful, set the file type to YAML - if yamlErr == nil { - fileType = ftYAML - mappedFileData = data - return - } - - // Otherwise, the file type is unsupported - fmt.Println("Unsupported file type.") - os.Exit(1) -} - -// buildStructFromData builds a struct from the YAML data -func buildStructFromData() string { - // Create a struct from the YAML data - structOutput = "type " + structName + " struct {\n" - structOutput += structBuilder(mappedFileData, "\t") - structOutput += "}" - - return structOutput -} - -// structBuilder builds a struct from the provided data -func structBuilder(data map[interface{}]interface{}, prefix string) string { - // Initialize the struct fields - var structFields string - - // Iterate over the data - for key, value := range data { - // Get the type of the value - var fieldType string - - // Check the type of the value - switch v := value.(type) { - case map[interface{}]interface{}: - fieldType = "struct {\n" + structBuilder(v, prefix+"\t") + prefix + "}" - case []interface{}: - if len(v) > 0 { - // Check if the first element is a map - if _, ok := v[0].(map[interface{}]interface{}); ok { - // If it's a map, generate a slice of structs - fieldType = "[]struct {\n" + structBuilder(v[0].(map[interface{}]interface{}), prefix+"\t") + prefix + "}" - } else { - // If it's not a map, use the existing logic - types := make(map[string]bool) - for _, elem := range v { - types[getType(elem)] = true - } - if len(types) == 1 { - for t := range types { - fieldType = "[]" + t - } - } else { - fieldType = "[]interface{}" - } - } - } else { - fieldType = "[]interface{}" - } - default: - fieldType = getType(v) - } - keyStr := fmt.Sprintf("%v", key) - structFields += prefix + fmt.Sprintf("%s %s `"+fileType+":\"%s\"`\n", strings.Title(keyStr), fieldType, key) - } - - return structFields -} - -// getType returns the type of the provided value -func getType(v interface{}) string { - switch v := v.(type) { - case string: - return "string" - case float64: - return "float64" - case int: - if math.Abs(float64(v)) > math.MaxInt32 { - return "int64" - } else { - return "int" - } - case bool: - return "bool" - case []interface{}: - return "[]interface{}" - case map[interface{}]interface{}: - return "struct {\n" + structBuilder(v, "\t") + "}\n" - - default: - return "interface{}" - } -}