package internal import ( "encoding/json" "fmt" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" "strconv" "sync/atomic" ) var ( _ Value = (*atomicValue)(nil) _ Value = (*errValue)(nil) ) // Value is config value interface. type Value interface { Bool() bool Int() int64 Float() float64 String() string Scan(interface{}) error Load() interface{} Store(interface{}) } type atomicValue struct { atomic.Value } func (v *atomicValue) Bool() bool { switch val := v.Load().(type) { case bool: return val case int, int32, int64, float64, string: v, err := strconv.ParseBool(fmt.Sprint(val)) if err == nil { return v } } return false } func (v *atomicValue) Int() int64 { switch val := v.Load().(type) { case int: return int64(val) case int32: return int64(val) case int64: return val case float64: return int64(val) case string: v, err := strconv.ParseInt(val, 10, 64) if err == nil { return v } } return 0 } func (v *atomicValue) Float() float64 { switch val := v.Load().(type) { case float64: return val case int: return float64(val) case int32: return float64(val) case int64: return float64(val) case string: v, err := strconv.ParseFloat(val, 64) if err == nil { return v } } return 0.0 } func (v *atomicValue) String() string { switch val := v.Load().(type) { case string: return val case bool, int, int32, int64, float64: return fmt.Sprint(val) case []byte: return string(val) default: if s, ok := val.(fmt.Stringer); ok { return s.String() } } return "" } func (v *atomicValue) Scan(obj interface{}) error { data, err := json.Marshal(v.Load()) if err != nil { return err } if pb, ok := obj.(proto.Message); ok { return protojson.Unmarshal(data, pb) } return json.Unmarshal(data, obj) } type errValue struct { err error } func (v errValue) Bool() bool { return false } func (v errValue) Int() int64 { return 0 } func (v errValue) Float() float64 { return 0.0 } func (v errValue) String() string { return "" } func (v errValue) Scan(interface{}) error { return v.err } func (v errValue) Load() interface{} { return nil } func (v errValue) Store(interface{}) {}