github.com/linuxboot/fiano@v1.2.0/pkg/intel/metadata/common/pretty/pretty.go (about)

     1  // Copyright 2017-2021 the LinuxBoot Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package pretty
     6  
     7  import (
     8  	"fmt"
     9  	"reflect"
    10  	"strings"
    11  
    12  	"github.com/dustin/go-humanize"
    13  )
    14  
    15  func Header(depth uint, description string, obj interface{}) string {
    16  	if description == "" {
    17  		description = fmt.Sprintf("%T", obj)
    18  	}
    19  	switch depth {
    20  	case 0:
    21  		description = `----` + description + "----\n"
    22  	case 1:
    23  		description = `--` + description + `--`
    24  	default:
    25  		description += `:`
    26  	}
    27  	description = strings.Repeat("  ", int(depth)) + description
    28  	return description
    29  }
    30  
    31  func SubValue(depth uint, fieldName, valueDescription string, value interface{}, opts ...Option) []string {
    32  	cfg := getConfig(opts)
    33  	if cfg.OmitKeySignature {
    34  		switch fieldName {
    35  		case "PMSE: Signature", "Key And Signature":
    36  			return nil
    37  		}
    38  	}
    39  
    40  	if valueDescription == "" {
    41  		valueDescription = getDescriptionForValue(depth, value, opts...)
    42  	}
    43  	return []string{fmt.Sprintf("%s %s", Header(depth, fieldName, nil), valueDescription)}
    44  }
    45  
    46  func getDescriptionForValue(depth uint, value interface{}, opts ...Option) string {
    47  	v := reflect.ValueOf(value)
    48  	if v.Kind() == reflect.Ptr && v.IsNil() {
    49  		return "is not set (nil)"
    50  	}
    51  
    52  	switch value := value.(type) {
    53  	case interface {
    54  		PrettyString(depth uint, withHeader bool, opts ...Option) string
    55  	}:
    56  		description := value.PrettyString(depth, false, opts...)
    57  		if len(strings.Split(description, "\n")) > 1 {
    58  			return "\n" + description
    59  		} else {
    60  			return strings.TrimSpace(description)
    61  		}
    62  	case fmt.GoStringer:
    63  		return value.GoString()
    64  	case fmt.Stringer:
    65  		return value.String()
    66  	}
    67  
    68  	v = reflect.Indirect(v)
    69  	switch v.Kind() {
    70  	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
    71  		i := v.Uint()
    72  		var hexFmt string
    73  		switch v.Type().Size() {
    74  		case 1:
    75  			hexFmt = "0x%02X"
    76  		case 2:
    77  			hexFmt = "0x%04X"
    78  		case 4:
    79  			hexFmt = "0x%08X"
    80  		case 8:
    81  			hexFmt = "0x%16X"
    82  		}
    83  		switch {
    84  		case i < 10:
    85  			return fmt.Sprintf(hexFmt, i)
    86  		case i < 65536:
    87  			return fmt.Sprintf(hexFmt+" (%d)", i, i)
    88  		default:
    89  			return fmt.Sprintf(hexFmt+" (%d: %s)", i, i, humanize.IBytes(i))
    90  		}
    91  
    92  	case reflect.Array:
    93  		return fmt.Sprintf("0x%X", v.Interface())
    94  
    95  	case reflect.Slice:
    96  		if v.Len() == 0 {
    97  			return "empty (len: 0)"
    98  		}
    99  		return fmt.Sprintf("0x%X (len: %d)", v.Interface(), v.Len())
   100  	}
   101  
   102  	return fmt.Sprintf("%#+v (%T)", value, value)
   103  }