main.go 1.9 KB

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