github.com/weaviate/weaviate@v1.24.6/usecases/modulecomponents/settings/class_settings_property_helper.go (about)

     1  //                           _       _
     2  // __      _____  __ ___   ___  __ _| |_ ___
     3  // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
     4  //  \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
     5  //   \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
     6  //
     7  //  Copyright © 2016 - 2024 Weaviate B.V. All rights reserved.
     8  //
     9  //  CONTACT: hello@weaviate.io
    10  //
    11  
    12  package settings
    13  
    14  import (
    15  	"encoding/json"
    16  	"fmt"
    17  	"strconv"
    18  
    19  	"github.com/weaviate/weaviate/entities/moduletools"
    20  )
    21  
    22  type PropertyValuesHelper interface {
    23  	GetPropertyAsInt(cfg moduletools.ClassConfig, name string, defaultValue *int) *int
    24  	GetPropertyAsIntWithNotExists(cfg moduletools.ClassConfig, name string, defaultValue, notExistsValue *int) *int
    25  	GetPropertyAsInt64(cfg moduletools.ClassConfig, name string, defaultValue *int64) *int64
    26  	GetPropertyAsInt64WithNotExists(cfg moduletools.ClassConfig, name string, defaultValue, notExistsValue *int64) *int64
    27  	GetPropertyAsFloat64(cfg moduletools.ClassConfig, name string, defaultValue *float64) *float64
    28  	GetPropertyAsFloat64WithNotExists(cfg moduletools.ClassConfig, name string, defaultValue, notExistsValue *float64) *float64
    29  	GetPropertyAsString(cfg moduletools.ClassConfig, name, defaultValue string) string
    30  	GetPropertyAsStringWithNotExists(cfg moduletools.ClassConfig, name, defaultValue, notExistsValue string) string
    31  	GetPropertyAsBool(cfg moduletools.ClassConfig, name string, defaultValue bool) bool
    32  	GetPropertyAsBoolWithNotExists(cfg moduletools.ClassConfig, name string, defaultValue, notExistsValue bool) bool
    33  	GetNumber(in interface{}) (float32, error)
    34  }
    35  
    36  type classPropertyValuesHelper struct {
    37  	moduleName string
    38  }
    39  
    40  func NewPropertyValuesHelper(moduleName string) PropertyValuesHelper {
    41  	return &classPropertyValuesHelper{moduleName}
    42  }
    43  
    44  func (h *classPropertyValuesHelper) GetPropertyAsInt(cfg moduletools.ClassConfig,
    45  	name string, defaultValue *int,
    46  ) *int {
    47  	return h.GetPropertyAsIntWithNotExists(cfg, name, defaultValue, defaultValue)
    48  }
    49  
    50  func (h *classPropertyValuesHelper) GetPropertyAsIntWithNotExists(cfg moduletools.ClassConfig,
    51  	name string, defaultValue, notExistsValue *int,
    52  ) *int {
    53  	if cfg == nil {
    54  		// we would receive a nil-config on cross-class requests, such as Explore{}
    55  		return notExistsValue
    56  	}
    57  	return getNumberValue(h.getSettings(cfg), name, defaultValue, notExistsValue)
    58  }
    59  
    60  func (h *classPropertyValuesHelper) GetPropertyAsInt64(cfg moduletools.ClassConfig,
    61  	name string, defaultValue *int64,
    62  ) *int64 {
    63  	return h.GetPropertyAsInt64WithNotExists(cfg, name, defaultValue, defaultValue)
    64  }
    65  
    66  func (h *classPropertyValuesHelper) GetPropertyAsInt64WithNotExists(cfg moduletools.ClassConfig,
    67  	name string, defaultValue, notExistsValue *int64,
    68  ) *int64 {
    69  	if cfg == nil {
    70  		// we would receive a nil-config on cross-class requests, such as Explore{}
    71  		return notExistsValue
    72  	}
    73  	return getNumberValue(h.getSettings(cfg), name, defaultValue, notExistsValue)
    74  }
    75  
    76  func (h *classPropertyValuesHelper) GetPropertyAsFloat64(cfg moduletools.ClassConfig,
    77  	name string, defaultValue *float64,
    78  ) *float64 {
    79  	return h.GetPropertyAsFloat64WithNotExists(cfg, name, defaultValue, defaultValue)
    80  }
    81  
    82  func (h *classPropertyValuesHelper) GetPropertyAsFloat64WithNotExists(cfg moduletools.ClassConfig,
    83  	name string, defaultValue, notExistsValue *float64,
    84  ) *float64 {
    85  	if cfg == nil {
    86  		// we would receive a nil-config on cross-class requests, such as Explore{}
    87  		return notExistsValue
    88  	}
    89  	return getNumberValue(h.getSettings(cfg), name, defaultValue, notExistsValue)
    90  }
    91  
    92  func (h *classPropertyValuesHelper) GetPropertyAsString(cfg moduletools.ClassConfig,
    93  	name, defaultValue string,
    94  ) string {
    95  	return h.GetPropertyAsStringWithNotExists(cfg, name, defaultValue, defaultValue)
    96  }
    97  
    98  func (h *classPropertyValuesHelper) GetPropertyAsStringWithNotExists(cfg moduletools.ClassConfig,
    99  	name, defaultValue, notExistsValue string,
   100  ) string {
   101  	if cfg == nil {
   102  		// we would receive a nil-config on cross-class requests, such as Explore{}
   103  		return notExistsValue
   104  	}
   105  
   106  	value := h.getSettings(cfg)[name]
   107  	switch v := value.(type) {
   108  	case nil:
   109  		return notExistsValue
   110  	case string:
   111  		return v
   112  	default:
   113  		return defaultValue
   114  	}
   115  }
   116  
   117  func (h *classPropertyValuesHelper) GetPropertyAsBool(cfg moduletools.ClassConfig,
   118  	name string, defaultValue bool,
   119  ) bool {
   120  	return h.GetPropertyAsBoolWithNotExists(cfg, name, defaultValue, defaultValue)
   121  }
   122  
   123  func (h *classPropertyValuesHelper) GetPropertyAsBoolWithNotExists(cfg moduletools.ClassConfig,
   124  	name string, defaultValue, notExistsValue bool,
   125  ) bool {
   126  	if cfg == nil {
   127  		// we would receive a nil-config on cross-class requests, such as Explore{}
   128  		return notExistsValue
   129  	}
   130  
   131  	value := h.getSettings(cfg)[name]
   132  	switch v := value.(type) {
   133  	case nil:
   134  		return notExistsValue
   135  	case bool:
   136  		return v
   137  	case string:
   138  		asBool, err := strconv.ParseBool(v)
   139  		if err == nil {
   140  			return asBool
   141  		}
   142  		return defaultValue
   143  	default:
   144  		return defaultValue
   145  	}
   146  }
   147  
   148  func (h *classPropertyValuesHelper) GetNumber(in interface{}) (float32, error) {
   149  	switch i := in.(type) {
   150  	case float64:
   151  		return float32(i), nil
   152  	case float32:
   153  		return i, nil
   154  	case int:
   155  		return float32(i), nil
   156  	case string:
   157  		num, err := strconv.ParseFloat(i, 64)
   158  		if err != nil {
   159  			return 0, err
   160  		}
   161  		return float32(num), err
   162  	case json.Number:
   163  		num, err := i.Float64()
   164  		if err != nil {
   165  			return 0, err
   166  		}
   167  		return float32(num), err
   168  	default:
   169  		return 0.0, fmt.Errorf("Unrecognized type: %T", in)
   170  	}
   171  }
   172  
   173  func (h *classPropertyValuesHelper) getSettings(cfg moduletools.ClassConfig) map[string]interface{} {
   174  	if h.moduleName != "" {
   175  		return cfg.ClassByModuleName(h.moduleName)
   176  	}
   177  	return cfg.Class()
   178  }
   179  
   180  func getNumberValue[T int | int64 | float64](settings map[string]interface{},
   181  	name string, defaultValue, notExistsValue *T,
   182  ) *T {
   183  	value := settings[name]
   184  	switch v := value.(type) {
   185  	case nil:
   186  		return notExistsValue
   187  	case json.Number:
   188  		if asInt64V, err := v.Int64(); err == nil {
   189  			return asNumber[int64, T](asInt64V)
   190  		}
   191  		return defaultValue
   192  	case float32:
   193  		return asNumber[float32, T](v)
   194  	case float64:
   195  		return asNumber[float64, T](v)
   196  	case int:
   197  		return asNumber[int, T](v)
   198  	case int16:
   199  		return asNumber[int16, T](v)
   200  	case int32:
   201  		return asNumber[int32, T](v)
   202  	case int64:
   203  		return asNumber[int64, T](v)
   204  	case string:
   205  		if asInt, err := strconv.Atoi(v); err == nil {
   206  			return asNumber[int, T](asInt)
   207  		}
   208  		return defaultValue
   209  	default:
   210  		return defaultValue
   211  	}
   212  }
   213  
   214  func asNumber[T int | int16 | int32 | int64 | float32 | float64, R int | int64 | float64](v T) *R {
   215  	number := R(v)
   216  	return &number
   217  }