go-hep.org/x/hep@v0.38.1/groot/rsql/rsqldrv/types.go (about)

     1  // Copyright ©2019 The go-hep 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 rsqldrv // import "go-hep.org/x/hep/groot/rsql/rsqldrv"
     6  
     7  import (
     8  	"fmt"
     9  	"math"
    10  	"reflect"
    11  
    12  	"go-hep.org/x/hep/groot/rtree"
    13  )
    14  
    15  type (
    16  	idealFloat float64
    17  	idealInt   int64
    18  	idealUint  uint64
    19  )
    20  
    21  func coerce(a, b any) (x, y any) {
    22  	if reflect.TypeOf(a) == reflect.TypeOf(b) {
    23  		return a, b
    24  	}
    25  
    26  	switch a.(type) {
    27  	case idealFloat, idealInt, idealUint:
    28  		switch b.(type) {
    29  		case idealFloat, idealInt, idealUint:
    30  			x, y = coerce1(a, b), b
    31  			if reflect.TypeOf(x) == reflect.TypeOf(y) {
    32  				return
    33  			}
    34  
    35  			return a, coerce1(b, a)
    36  		default:
    37  			return coerce1(a, b), b
    38  		}
    39  	default:
    40  		switch b.(type) {
    41  		case idealFloat, idealInt, idealUint:
    42  			return a, coerce1(b, a)
    43  		default:
    44  			return a, b
    45  		}
    46  	}
    47  }
    48  
    49  func coerce1(inVal, otherVal any) (coercedInVal any) {
    50  	coercedInVal = inVal
    51  	if otherVal == nil {
    52  		return
    53  	}
    54  
    55  	switch x := inVal.(type) {
    56  	case nil:
    57  		return
    58  	case idealFloat:
    59  		switch otherVal.(type) {
    60  		case idealFloat:
    61  			return idealFloat(float64(x))
    62  		//case idealInt:
    63  		//case idealRune:
    64  		//case idealUint:
    65  		//case bool:
    66  		case float32:
    67  			return float32(float64(x))
    68  		case float64:
    69  			return float64(x)
    70  			//case int8:
    71  			//case int16:
    72  			//case int32:
    73  			//case int64:
    74  			//case string:
    75  			//case uint8:
    76  			//case uint16:
    77  			//case uint32:
    78  			//case uint64:
    79  		}
    80  	case idealInt:
    81  		switch otherVal.(type) {
    82  		case idealFloat:
    83  			return idealFloat(int64(x))
    84  		case idealInt:
    85  			return idealInt(int64(x))
    86  		//case idealRune:
    87  		case idealUint:
    88  			if x >= 0 {
    89  				return idealUint(int64(x))
    90  			}
    91  		//case bool:
    92  		case float32:
    93  			return float32(int64(x))
    94  		case float64:
    95  			return float64(int64(x))
    96  		case int8:
    97  			if x >= math.MinInt8 && x <= math.MaxInt8 {
    98  				return int8(int64(x))
    99  			}
   100  		case int16:
   101  			if x >= math.MinInt16 && x <= math.MaxInt16 {
   102  				return int16(int64(x))
   103  			}
   104  		case int32:
   105  			if x >= math.MinInt32 && x <= math.MaxInt32 {
   106  				return int32(int64(x))
   107  			}
   108  		case int64:
   109  			return int64(x)
   110  		//case string:
   111  		case uint8:
   112  			if x >= 0 && x <= math.MaxUint8 {
   113  				return uint8(int64(x))
   114  			}
   115  		case uint16:
   116  			if x >= 0 && x <= math.MaxUint16 {
   117  				return uint16(int64(x))
   118  			}
   119  		case uint32:
   120  			if x >= 0 && x <= math.MaxUint32 {
   121  				return uint32(int64(x))
   122  			}
   123  		case uint64:
   124  			if x >= 0 {
   125  				return uint64(int64(x))
   126  			}
   127  		}
   128  	case idealUint:
   129  		switch otherVal.(type) {
   130  		case idealFloat:
   131  			return idealFloat(uint64(x))
   132  		case idealInt:
   133  			if x <= math.MaxInt64 {
   134  				return idealInt(int64(x))
   135  			}
   136  		//case idealRune:
   137  		case idealUint:
   138  			return idealUint(uint64(x))
   139  		//case bool:
   140  		case float32:
   141  			return float32(uint64(x))
   142  		case float64:
   143  			return float64(uint64(x))
   144  		case int8:
   145  			if x <= math.MaxInt8 {
   146  				return int8(int64(x))
   147  			}
   148  		case int16:
   149  			if x <= math.MaxInt16 {
   150  				return int16(int64(x))
   151  			}
   152  		case int32:
   153  			if x <= math.MaxInt32 {
   154  				return int32(int64(x))
   155  			}
   156  		case int64:
   157  			if x <= math.MaxInt64 {
   158  				return int64(x)
   159  			}
   160  		//case string:
   161  		case uint8:
   162  			if x <= math.MaxUint8 {
   163  				return uint8(int64(x))
   164  			}
   165  		case uint16:
   166  			if x <= math.MaxUint16 {
   167  				return uint16(int64(x))
   168  			}
   169  		case uint32:
   170  			if x <= math.MaxUint32 {
   171  				return uint32(int64(x))
   172  			}
   173  		case uint64:
   174  			return uint64(x)
   175  		}
   176  	}
   177  	return
   178  }
   179  
   180  func colDescrFromLeaf(leaf rtree.Leaf) colDescr {
   181  	name := leaf.Name()
   182  	etyp := leaf.Type()
   183  	kind := leaf.Kind()
   184  	hasCount := leaf.LeafCount() != nil
   185  	unsigned := leaf.IsUnsigned()
   186  
   187  	size := 1
   188  	if !hasCount {
   189  		size = leaf.Len()
   190  	}
   191  
   192  	return colDescrFrom(name, etyp, kind, hasCount, size, unsigned)
   193  }
   194  
   195  func colDescrFrom(name string, etyp reflect.Type, kind reflect.Kind, hasCount bool, size int, unsigned bool) colDescr {
   196  	col := colDescr{
   197  		Name: name,
   198  		Len:  -1,
   199  	}
   200  
   201  	switch {
   202  	case hasCount:
   203  		// slice
   204  		col.Nullable = true
   205  		col.Len = math.MaxInt64
   206  	case size > 1 && kind != reflect.String:
   207  		// array
   208  		col.Len = int64(size)
   209  	}
   210  
   211  	switch etyp.Kind() {
   212  	case reflect.Interface, reflect.Map, reflect.Chan, reflect.Slice, reflect.Array:
   213  		panic(fmt.Errorf("rsqldrv: type %T not supported", reflect.New(etyp).Elem().Interface()))
   214  	case reflect.Int8:
   215  		if unsigned {
   216  			etyp = reflect.TypeOf(uint8(0))
   217  		}
   218  	case reflect.Int16:
   219  		if unsigned {
   220  			etyp = reflect.TypeOf(uint16(0))
   221  		}
   222  	case reflect.Int32:
   223  		if unsigned {
   224  			etyp = reflect.TypeOf(uint32(0))
   225  		}
   226  	case reflect.Int64:
   227  		if unsigned {
   228  			etyp = reflect.TypeOf(uint64(0))
   229  		}
   230  	}
   231  
   232  	col.Type = etyp
   233  	return col
   234  }