main.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package main
  2. import (
  3. "encoding/json"
  4. "flag"
  5. "fmt"
  6. "log"
  7. "os"
  8. "path"
  9. "time"
  10. "github.com/coreos/etcd/third_party/github.com/BurntSushi/toml"
  11. )
  12. func init() {
  13. log.SetFlags(0)
  14. flag.Usage = usage
  15. flag.Parse()
  16. }
  17. func usage() {
  18. log.Printf("Usage: %s < toml-file\n", path.Base(os.Args[0]))
  19. flag.PrintDefaults()
  20. os.Exit(1)
  21. }
  22. func main() {
  23. if flag.NArg() != 0 {
  24. flag.Usage()
  25. }
  26. var tmp interface{}
  27. if _, err := toml.DecodeReader(os.Stdin, &tmp); err != nil {
  28. log.Fatalf("Error decoding TOML: %s", err)
  29. }
  30. typedTmp := translate(tmp)
  31. if err := json.NewEncoder(os.Stdout).Encode(typedTmp); err != nil {
  32. log.Fatalf("Error encoding JSON: %s", err)
  33. }
  34. }
  35. func translate(tomlData interface{}) interface{} {
  36. switch orig := tomlData.(type) {
  37. case map[string]interface{}:
  38. typed := make(map[string]interface{}, len(orig))
  39. for k, v := range orig {
  40. typed[k] = translate(v)
  41. }
  42. return typed
  43. case []map[string]interface{}:
  44. typed := make([]map[string]interface{}, len(orig))
  45. for i, v := range orig {
  46. typed[i] = translate(v).(map[string]interface{})
  47. }
  48. return typed
  49. case []interface{}:
  50. typed := make([]interface{}, len(orig))
  51. for i, v := range orig {
  52. typed[i] = translate(v)
  53. }
  54. // We don't really need to tag arrays, but let's be future proof.
  55. // (If TOML ever supports tuples, we'll need this.)
  56. return tag("array", typed)
  57. case time.Time:
  58. return tag("datetime", orig.Format("2006-01-02T15:04:05Z"))
  59. case bool:
  60. return tag("bool", fmt.Sprintf("%v", orig))
  61. case int64:
  62. return tag("integer", fmt.Sprintf("%d", orig))
  63. case float64:
  64. return tag("float", fmt.Sprintf("%v", orig))
  65. case string:
  66. return tag("string", orig)
  67. }
  68. panic(fmt.Sprintf("Unknown type: %T", tomlData))
  69. }
  70. func tag(typeName string, data interface{}) map[string]interface{} {
  71. return map[string]interface{}{
  72. "type": typeName,
  73. "value": data,
  74. }
  75. }