golang.org/x/exp@v0.0.0-20240506185415-9bf2ced13842/slog/value_119.go (about)

     1  // Copyright 2022 The Go 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  //go:build go1.19 && !go1.20
     6  
     7  package slog
     8  
     9  import (
    10  	"reflect"
    11  	"unsafe"
    12  )
    13  
    14  type (
    15  	stringptr unsafe.Pointer // used in Value.any when the Value is a string
    16  	groupptr  unsafe.Pointer // used in Value.any when the Value is a []Attr
    17  )
    18  
    19  // StringValue returns a new Value for a string.
    20  func StringValue(value string) Value {
    21  	hdr := (*reflect.StringHeader)(unsafe.Pointer(&value))
    22  	return Value{num: uint64(hdr.Len), any: stringptr(hdr.Data)}
    23  }
    24  
    25  func (v Value) str() string {
    26  	var s string
    27  	hdr := (*reflect.StringHeader)(unsafe.Pointer(&s))
    28  	hdr.Data = uintptr(v.any.(stringptr))
    29  	hdr.Len = int(v.num)
    30  	return s
    31  }
    32  
    33  // String returns Value's value as a string, formatted like fmt.Sprint. Unlike
    34  // the methods Int64, Float64, and so on, which panic if v is of the
    35  // wrong kind, String never panics.
    36  func (v Value) String() string {
    37  	if sp, ok := v.any.(stringptr); ok {
    38  		// Inlining this code makes a huge difference.
    39  		var s string
    40  		hdr := (*reflect.StringHeader)(unsafe.Pointer(&s))
    41  		hdr.Data = uintptr(sp)
    42  		hdr.Len = int(v.num)
    43  		return s
    44  	}
    45  	return string(v.append(nil))
    46  }
    47  
    48  // GroupValue returns a new Value for a list of Attrs.
    49  // The caller must not subsequently mutate the argument slice.
    50  func GroupValue(as ...Attr) Value {
    51  	hdr := (*reflect.SliceHeader)(unsafe.Pointer(&as))
    52  	return Value{num: uint64(hdr.Len), any: groupptr(hdr.Data)}
    53  }