github.com/hashicorp/packer@v1.14.3/hcl2template/repl/format.go (about)

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