github.com/ssgreg/logf@v1.4.1/snapshotter.go (about)

     1  package logf
     2  
     3  import (
     4  	"time"
     5  	"unsafe"
     6  )
     7  
     8  // Snapshotter is the interface that allows to do a custom copy of a logging
     9  // object. If the object type implements TaskSnapshot function it will be
    10  // called during the logging procedure in a caller's goroutine.
    11  type Snapshotter interface {
    12  	TakeSnapshot() interface{}
    13  }
    14  
    15  // snapshotField calls an appropriate function to snapshot a Field.
    16  func snapshotField(f *Field) {
    17  	if f.Type&FieldTypeRawMask != 0 {
    18  		switch f.Type {
    19  		case FieldTypeRawBytes:
    20  			snapshotRawBytes(f)
    21  		case FieldTypeRawBytesToBools:
    22  			snapshotRawBytesToBools(f)
    23  		case FieldTypeRawBytesToInts64:
    24  			snapshotRawBytesToInts64(f)
    25  		case FieldTypeRawBytesToInts32:
    26  			snapshotRawBytesToInts32(f)
    27  		case FieldTypeRawBytesToInts16:
    28  			snapshotRawBytesToInts16(f)
    29  		case FieldTypeRawBytesToInts8:
    30  			snapshotRawBytesToInts8(f)
    31  		case FieldTypeRawBytesToUints64:
    32  			snapshotRawBytesToUints64(f)
    33  		case FieldTypeRawBytesToUints32:
    34  			snapshotRawBytesToUints32(f)
    35  		case FieldTypeRawBytesToUints16:
    36  			snapshotRawBytesToUints16(f)
    37  		case FieldTypeRawBytesToUints8:
    38  			snapshotRawBytesToUints8(f)
    39  		case FieldTypeRawBytesToFloats64:
    40  			snapshotRawBytesToFloats64(f)
    41  		case FieldTypeRawBytesToFloats32:
    42  			snapshotRawBytesToFloats32(f)
    43  		case FieldTypeRawBytesToDurations:
    44  			snapshotRawBytesToDurations(f)
    45  		}
    46  	}
    47  	if f.Type == FieldTypeAny {
    48  		if f.Any == nil {
    49  			return
    50  		}
    51  		switch rv := f.Any.(type) {
    52  		case Snapshotter:
    53  			f.Any = rv.TakeSnapshot()
    54  		}
    55  	}
    56  }
    57  
    58  func snapshotRawBytes(f *Field) {
    59  	cc := make([]byte, len(f.Bytes))
    60  	copy(cc, f.Bytes)
    61  	f.Bytes = cc
    62  	f.Type = FieldTypeBytes
    63  }
    64  
    65  func snapshotRawBytesToBools(f *Field) {
    66  	s := *(*[]bool)(unsafe.Pointer(&f.Bytes))
    67  	cc := make([]bool, len(s))
    68  	copy(cc, s)
    69  	f.Bytes = *(*[]byte)(unsafe.Pointer(&cc))
    70  	f.Type = FieldTypeBytesToBools
    71  }
    72  
    73  func snapshotRawBytesToInts64(f *Field) {
    74  	s := *(*[]int64)(unsafe.Pointer(&f.Bytes))
    75  	cc := make([]int64, len(s))
    76  	copy(cc, s)
    77  	f.Bytes = *(*[]byte)(unsafe.Pointer(&cc))
    78  	f.Type = FieldTypeBytesToInts64
    79  }
    80  
    81  func snapshotRawBytesToInts32(f *Field) {
    82  	s := *(*[]int32)(unsafe.Pointer(&f.Bytes))
    83  	cc := make([]int32, len(s))
    84  	copy(cc, s)
    85  	f.Bytes = *(*[]byte)(unsafe.Pointer(&cc))
    86  	f.Type = FieldTypeBytesToInts32
    87  }
    88  
    89  func snapshotRawBytesToInts16(f *Field) {
    90  	s := *(*[]int16)(unsafe.Pointer(&f.Bytes))
    91  	cc := make([]int16, len(s))
    92  	copy(cc, s)
    93  	f.Bytes = *(*[]byte)(unsafe.Pointer(&cc))
    94  	f.Type = FieldTypeBytesToInts16
    95  }
    96  
    97  func snapshotRawBytesToInts8(f *Field) {
    98  	s := *(*[]int8)(unsafe.Pointer(&f.Bytes))
    99  	cc := make([]int8, len(s))
   100  	copy(cc, s)
   101  	f.Bytes = *(*[]byte)(unsafe.Pointer(&cc))
   102  	f.Type = FieldTypeBytesToInts8
   103  }
   104  
   105  func snapshotRawBytesToUints64(f *Field) {
   106  	s := *(*[]uint64)(unsafe.Pointer(&f.Bytes))
   107  	cc := make([]uint64, len(s))
   108  	copy(cc, s)
   109  	f.Bytes = *(*[]byte)(unsafe.Pointer(&cc))
   110  	f.Type = FieldTypeBytesToUints64
   111  }
   112  
   113  func snapshotRawBytesToUints32(f *Field) {
   114  	s := *(*[]uint32)(unsafe.Pointer(&f.Bytes))
   115  	cc := make([]uint32, len(s))
   116  	copy(cc, s)
   117  	f.Bytes = *(*[]byte)(unsafe.Pointer(&cc))
   118  	f.Type = FieldTypeBytesToUints32
   119  }
   120  
   121  func snapshotRawBytesToUints16(f *Field) {
   122  	s := *(*[]uint16)(unsafe.Pointer(&f.Bytes))
   123  	cc := make([]uint16, len(s))
   124  	copy(cc, s)
   125  	f.Bytes = *(*[]byte)(unsafe.Pointer(&cc))
   126  	f.Type = FieldTypeBytesToUints16
   127  }
   128  
   129  func snapshotRawBytesToUints8(f *Field) {
   130  	s := *(*[]uint8)(unsafe.Pointer(&f.Bytes))
   131  	cc := make([]uint8, len(s))
   132  	copy(cc, s)
   133  	f.Bytes = *(*[]byte)(unsafe.Pointer(&cc))
   134  	f.Type = FieldTypeBytesToUints8
   135  }
   136  
   137  func snapshotRawBytesToFloats64(f *Field) {
   138  	s := *(*[]float64)(unsafe.Pointer(&f.Bytes))
   139  	cc := make([]float64, len(s))
   140  	copy(cc, s)
   141  	f.Bytes = *(*[]byte)(unsafe.Pointer(&cc))
   142  	f.Type = FieldTypeBytesToFloats64
   143  }
   144  
   145  func snapshotRawBytesToFloats32(f *Field) {
   146  	s := *(*[]float32)(unsafe.Pointer(&f.Bytes))
   147  	cc := make([]float32, len(s))
   148  	copy(cc, s)
   149  	f.Bytes = *(*[]byte)(unsafe.Pointer(&cc))
   150  	f.Type = FieldTypeBytesToFloats32
   151  }
   152  
   153  func snapshotRawBytesToDurations(f *Field) {
   154  	s := *(*[]time.Duration)(unsafe.Pointer(&f.Bytes))
   155  	cc := make([]time.Duration, len(s))
   156  	copy(cc, s)
   157  	f.Bytes = *(*[]byte)(unsafe.Pointer(&cc))
   158  	f.Type = FieldTypeBytesToDurations
   159  }