1package main 2 3import ( 4 "encoding/json" 5 "fmt" 6 "io/ioutil" 7 "log" 8 "os" 9 "time" 10 11 "github.com/pelletier/go-toml" 12) 13 14func main() { 15 bytes, err := ioutil.ReadAll(os.Stdin) 16 if err != nil { 17 log.Fatalf("Error during TOML read: %s", err) 18 os.Exit(2) 19 } 20 tree, err := toml.Load(string(bytes)) 21 if err != nil { 22 log.Fatalf("Error during TOML load: %s", err) 23 os.Exit(1) 24 } 25 26 typedTree := translate(*tree) 27 28 if err := json.NewEncoder(os.Stdout).Encode(typedTree); err != nil { 29 log.Fatalf("Error encoding JSON: %s", err) 30 os.Exit(3) 31 } 32 33 os.Exit(0) 34} 35 36func translate(tomlData interface{}) interface{} { 37 switch orig := tomlData.(type) { 38 case map[string]interface{}: 39 typed := make(map[string]interface{}, len(orig)) 40 for k, v := range orig { 41 typed[k] = translate(v) 42 } 43 return typed 44 case *toml.Tree: 45 return translate(*orig) 46 case toml.Tree: 47 keys := orig.Keys() 48 typed := make(map[string]interface{}, len(keys)) 49 for _, k := range keys { 50 typed[k] = translate(orig.GetPath([]string{k})) 51 } 52 return typed 53 case []*toml.Tree: 54 typed := make([]map[string]interface{}, len(orig)) 55 for i, v := range orig { 56 typed[i] = translate(v).(map[string]interface{}) 57 } 58 return typed 59 case []map[string]interface{}: 60 typed := make([]map[string]interface{}, len(orig)) 61 for i, v := range orig { 62 typed[i] = translate(v).(map[string]interface{}) 63 } 64 return typed 65 case []interface{}: 66 typed := make([]interface{}, len(orig)) 67 for i, v := range orig { 68 typed[i] = translate(v) 69 } 70 return tag("array", typed) 71 case time.Time: 72 return tag("datetime", orig.Format("2006-01-02T15:04:05Z")) 73 case bool: 74 return tag("bool", fmt.Sprintf("%v", orig)) 75 case int64: 76 return tag("integer", fmt.Sprintf("%d", orig)) 77 case float64: 78 return tag("float", fmt.Sprintf("%v", orig)) 79 case string: 80 return tag("string", orig) 81 } 82 83 panic(fmt.Sprintf("Unknown type: %T", tomlData)) 84} 85 86func tag(typeName string, data interface{}) map[string]interface{} { 87 return map[string]interface{}{ 88 "type": typeName, 89 "value": data, 90 } 91} 92