github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/toml/cmd/toml-test-encoder/main.go (about)

     1  // Command toml-test-encoder satisfies the toml-test interface for testing
     2  // TOML encoders. Namely, it accepts JSON on stdin and outputs TOML on stdout.
     3  package main
     4  
     5  import (
     6  	"encoding/json"
     7  	"flag"
     8  	"log"
     9  	"os"
    10  	"path"
    11  	"strconv"
    12  	"time"
    13  
    14  	"github.com/BurntSushi/toml"
    15  )
    16  
    17  func init() {
    18  	log.SetFlags(0)
    19  
    20  	flag.Usage = usage
    21  	flag.Parse()
    22  }
    23  
    24  func usage() {
    25  	log.Printf("Usage: %s < json-file\n", path.Base(os.Args[0]))
    26  	flag.PrintDefaults()
    27  
    28  	os.Exit(1)
    29  }
    30  
    31  func main() {
    32  	if flag.NArg() != 0 {
    33  		flag.Usage()
    34  	}
    35  
    36  	var tmp interface{}
    37  	if err := json.NewDecoder(os.Stdin).Decode(&tmp); err != nil {
    38  		log.Fatalf("Error decoding JSON: %s", err)
    39  	}
    40  
    41  	tomlData := translate(tmp)
    42  	if err := toml.NewEncoder(os.Stdout).Encode(tomlData); err != nil {
    43  		log.Fatalf("Error encoding TOML: %s", err)
    44  	}
    45  }
    46  
    47  func translate(typedJson interface{}) interface{} {
    48  	switch v := typedJson.(type) {
    49  	case map[string]interface{}:
    50  		if len(v) == 2 && in("type", v) && in("value", v) {
    51  			return untag(v)
    52  		}
    53  		m := make(map[string]interface{}, len(v))
    54  		for k, v2 := range v {
    55  			m[k] = translate(v2)
    56  		}
    57  		return m
    58  	case []interface{}:
    59  		tabArray := make([]map[string]interface{}, len(v))
    60  		for i := range v {
    61  			if m, ok := translate(v[i]).(map[string]interface{}); ok {
    62  				tabArray[i] = m
    63  			} else {
    64  				log.Fatalf("JSON arrays may only contain objects. This " +
    65  					"corresponds to only tables being allowed in " +
    66  					"TOML table arrays.")
    67  			}
    68  		}
    69  		return tabArray
    70  	}
    71  	log.Fatalf("Unrecognized JSON format '%T'.", typedJson)
    72  	panic("unreachable")
    73  }
    74  
    75  func untag(typed map[string]interface{}) interface{} {
    76  	t := typed["type"].(string)
    77  	v := typed["value"]
    78  	switch t {
    79  	case "string":
    80  		return v.(string)
    81  	case "integer":
    82  		v := v.(string)
    83  		n, err := strconv.Atoi(v)
    84  		if err != nil {
    85  			log.Fatalf("Could not parse '%s' as integer: %s", v, err)
    86  		}
    87  		return n
    88  	case "float":
    89  		v := v.(string)
    90  		f, err := strconv.ParseFloat(v, 64)
    91  		if err != nil {
    92  			log.Fatalf("Could not parse '%s' as float64: %s", v, err)
    93  		}
    94  		return f
    95  	case "datetime":
    96  		v := v.(string)
    97  		t, err := time.Parse("2006-01-02T15:04:05Z", v)
    98  		if err != nil {
    99  			log.Fatalf("Could not parse '%s' as a datetime: %s", v, err)
   100  		}
   101  		return t
   102  	case "bool":
   103  		v := v.(string)
   104  		switch v {
   105  		case "true":
   106  			return true
   107  		case "false":
   108  			return false
   109  		}
   110  		log.Fatalf("Could not parse '%s' as a boolean.", v)
   111  	case "array":
   112  		v := v.([]interface{})
   113  		array := make([]interface{}, len(v))
   114  		for i := range v {
   115  			if m, ok := v[i].(map[string]interface{}); ok {
   116  				array[i] = untag(m)
   117  			} else {
   118  				log.Fatalf("Arrays may only contain other arrays or "+
   119  					"primitive values, but found a '%T'.", m)
   120  			}
   121  		}
   122  		return array
   123  	}
   124  	log.Fatalf("Unrecognized tag type '%s'.", t)
   125  	panic("unreachable")
   126  }
   127  
   128  func in(key string, m map[string]interface{}) bool {
   129  	_, ok := m[key]
   130  	return ok
   131  }