Created
November 10, 2024 09:33
-
-
Save gnuos/4a4ca5977c40b4aa813b79de1d0acd41 to your computer and use it in GitHub Desktop.
一个用于把YAML描述文件解析成Go语言代码的示例
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 代码用Go语言的反射示范了把YAML文件里面的字段抽取之后拼接打到控制台的实现方法 | |
| package main | |
| import ( | |
| "fmt" | |
| "log" | |
| "os" | |
| "strings" | |
| "github.com/goccy/go-yaml" | |
| ) | |
| const modelContent = `--- | |
| models: | |
| Student: | |
| Classes: | |
| type: "list" | |
| itemType: "string" | |
| Grade: | |
| type: "number" | |
| Person: | |
| Name: | |
| type: "string" | |
| Age: | |
| type: "number" | |
| Addresses: | |
| type: "list" | |
| itemType: "Address" | |
| Address: | |
| City: | |
| type: "string" | |
| Country: | |
| type: "string" | |
| ` | |
| func main() { | |
| log.Println("Loaded models yaml") | |
| var data map[string]interface{} | |
| var file = os.Stdout | |
| fmt.Printf(modelContent) | |
| if err := yaml.Unmarshal([]byte(modelContent), &data); err != nil { | |
| log.Fatalf("failed to unmarshal YAML data: %v", err) | |
| } | |
| modelsData, _ := data["models"].(map[string]interface{}) | |
| fmt.Fprintf(file, "package models\n") | |
| for modelName, modelFields := range modelsData { | |
| log.Printf("Load model- %s", modelName) | |
| fmt.Fprintf(file, "type %s struct {\n", modelName) | |
| generateFields(file, modelFields) | |
| fmt.Fprintf(file, "}\n") | |
| } | |
| log.Println("Successfully genereated models") | |
| } | |
| func generateFields(file *os.File, fields interface{}) { | |
| switch v := fields.(type) { | |
| case map[string]interface{}: | |
| for fieldName, fieldType := range v { | |
| jsonTagName := strings.ToLower(fmt.Sprintf("json:\"%s\"", fieldName)) | |
| fmt.Fprintf(file, "\t%s %s `%s`\n", fieldName, getGoType(fieldType), jsonTagName) | |
| } | |
| default: | |
| log.Fatal("unexpected type encountered while generating fields") | |
| } | |
| } | |
| func getGoType(fieldType interface{}) string { | |
| switch t := fieldType.(type) { | |
| case string: | |
| return mapYAMLTypeToGoType(t, nil) | |
| case map[interface{}]interface{}: | |
| if t["type"] != nil { | |
| if t["itemType"] != nil { | |
| return mapYAMLTypeToGoType(t["type"].(string), t["itemType"].(string)) | |
| } else { | |
| return mapYAMLTypeToGoType(t["type"].(string), nil) | |
| } | |
| } | |
| } | |
| return "" | |
| } | |
| func mapYAMLTypeToGoType(yamlType string, itemType interface{}) string { | |
| switch yamlType { | |
| case "list": | |
| if itemType != nil { | |
| return fmt.Sprintf("[]%s", itemType.(string)) | |
| } else { | |
| return "[]string" | |
| } | |
| case "number": | |
| return "float64" | |
| case "string": | |
| return "string" | |
| // Add more mappings as needed | |
| default: | |
| return "interface{}" // Default to interface{} for unknown types | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment