github.com/v2pro/plz@v0.0.0-20221028024117-e5f9aec5b631/msgfmt/msgfmt.go (about)

     1  package msgfmt
     2  
     3  import (
     4  	"io"
     5  	"os"
     6  	"sync"
     7  	"unsafe"
     8  	"fmt"
     9  	"github.com/v2pro/plz/concurrent"
    10  	"github.com/v2pro/plz/reflect2"
    11  )
    12  
    13  var bufPool = &sync.Pool{
    14  	New: func() interface{} {
    15  		return make([]byte, 0, 128)
    16  	},
    17  }
    18  
    19  func Sprintf(format string, kvObj ...interface{}) string {
    20  	ptr := reflect2.NoEscape(unsafe.Pointer(&kvObj))
    21  	kv := *(*[]interface{})(ptr)
    22  	buf := FormatterOf(format, kv).Format(nil, kv)
    23  	return string(buf)
    24  }
    25  
    26  func Println(valuesObj ...interface{}) (int, error) {
    27  	ptr := reflect2.NoEscape(unsafe.Pointer(&valuesObj))
    28  	values := *(*[]interface{})(ptr)
    29  	return fprintln(os.Stdout, values)
    30  }
    31  
    32  func Fprintln(writer io.Writer, valuesObj ...interface{}) (int, error) {
    33  	ptr := reflect2.NoEscape(unsafe.Pointer(&valuesObj))
    34  	values := *(*[]interface{})(ptr)
    35  	return fprintln(writer, values)
    36  }
    37  
    38  func fprintln(writer io.Writer, values []interface{}) (int, error) {
    39  	switch len(values) {
    40  	case 0:
    41  		return fmt.Println()
    42  	case 1:
    43  		return Fprintf(writer,"{single_value}\n", "single_value", values[0])
    44  	default:
    45  		return Fprintf(writer, "{multiple_values}\n", "multiple_values", values)
    46  	}
    47  }
    48  
    49  func Printf(format string, kvObj ...interface{}) (int, error) {
    50  	ptr := reflect2.NoEscape(unsafe.Pointer(&kvObj))
    51  	kv := *(*[]interface{})(ptr)
    52  	return fprintf(os.Stdout, format, kv)
    53  }
    54  
    55  func Fprintf(writer io.Writer, format string, kvObj ...interface{}) (int, error) {
    56  	ptr := reflect2.NoEscape(unsafe.Pointer(&kvObj))
    57  	kv := *(*[]interface{})(ptr)
    58  	return fprintf(writer, format, kv)
    59  }
    60  
    61  func fprintf(writer io.Writer, format string, kv []interface{}) (int, error) {
    62  	buf := bufPool.Get().([]byte)[:0]
    63  	formatter := FormatterOf(format, kv)
    64  	formatted := formatter.Format(buf, kv)
    65  	n, err := writer.Write(formatted)
    66  	bufPool.Put(formatted)
    67  	return n, err
    68  }
    69  
    70  var formatterCache = concurrent.NewMap()
    71  
    72  func FormatterOf(format string, sample []interface{}) Formatter {
    73  	formatterObj, found := formatterCache.Load(format)
    74  	if found {
    75  		return formatterObj.(Formatter)
    76  	}
    77  	formatter := compile(format, sample)
    78  	formatterCache.Store(format, formatter)
    79  	return formatter
    80  }