Skip to content

Instantly share code, notes, and snippets.

@gnuos
Created November 10, 2024 09:33
Show Gist options
  • Select an option

  • Save gnuos/4a4ca5977c40b4aa813b79de1d0acd41 to your computer and use it in GitHub Desktop.

Select an option

Save gnuos/4a4ca5977c40b4aa813b79de1d0acd41 to your computer and use it in GitHub Desktop.
一个用于把YAML描述文件解析成Go语言代码的示例
// 代码用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