github.com/Burmuley/terraform@v0.11.12-beta1/repl/format.go (about) 1 package repl 2 3 import ( 4 "bufio" 5 "bytes" 6 "fmt" 7 "sort" 8 "strings" 9 ) 10 11 // FormatResult formats the given result value for human-readable output. 12 // 13 // The value must currently be a string, list, map, and any nested values 14 // with those same types. 15 func FormatResult(value interface{}) (string, error) { 16 return formatResult(value, false) 17 } 18 19 func formatResult(value interface{}, nested bool) (string, error) { 20 switch output := value.(type) { 21 case string: 22 if nested { 23 return fmt.Sprintf("%q", output), nil 24 } 25 return output, nil 26 case []interface{}: 27 return formatListResult(output) 28 case map[string]interface{}: 29 return formatMapResult(output) 30 default: 31 return "", fmt.Errorf("unknown value type: %T", value) 32 } 33 } 34 35 func formatListResult(value []interface{}) (string, error) { 36 var outputBuf bytes.Buffer 37 outputBuf.WriteString("[") 38 if len(value) > 0 { 39 outputBuf.WriteString("\n") 40 } 41 42 for _, v := range value { 43 raw, err := formatResult(v, true) 44 if err != nil { 45 return "", err 46 } 47 48 outputBuf.WriteString(indent(raw)) 49 outputBuf.WriteString(",\n") 50 } 51 52 outputBuf.WriteString("]") 53 return outputBuf.String(), nil 54 } 55 56 func formatMapResult(value map[string]interface{}) (string, error) { 57 ks := make([]string, 0, len(value)) 58 for k, _ := range value { 59 ks = append(ks, k) 60 } 61 sort.Strings(ks) 62 63 var outputBuf bytes.Buffer 64 outputBuf.WriteString("{") 65 if len(value) > 0 { 66 outputBuf.WriteString("\n") 67 } 68 69 for _, k := range ks { 70 v := value[k] 71 rawK, err := formatResult(k, true) 72 if err != nil { 73 return "", err 74 } 75 rawV, err := formatResult(v, true) 76 if err != nil { 77 return "", err 78 } 79 80 outputBuf.WriteString(indent(fmt.Sprintf("%s = %s", rawK, rawV))) 81 outputBuf.WriteString("\n") 82 } 83 84 outputBuf.WriteString("}") 85 return outputBuf.String(), nil 86 } 87 88 func indent(value string) string { 89 var outputBuf bytes.Buffer 90 s := bufio.NewScanner(strings.NewReader(value)) 91 newline := false 92 for s.Scan() { 93 if newline { 94 outputBuf.WriteByte('\n') 95 } 96 outputBuf.WriteString(" " + s.Text()) 97 newline = true 98 } 99 100 return outputBuf.String() 101 }