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 }