update client
This commit is contained in:
141
value/value.go
141
value/value.go
@@ -1,8 +1,8 @@
|
||||
package value
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"gitoa.ru/go-4devs/config"
|
||||
@@ -10,6 +10,15 @@ import (
|
||||
|
||||
var _ config.Value = (*Value)(nil)
|
||||
|
||||
func New(data any) config.Value {
|
||||
switch val := data.(type) {
|
||||
case config.Value:
|
||||
return val
|
||||
default:
|
||||
return Value{Val: data}
|
||||
}
|
||||
}
|
||||
|
||||
type Value struct {
|
||||
Val any
|
||||
}
|
||||
@@ -62,10 +71,6 @@ func (s Value) Duration() time.Duration {
|
||||
return v
|
||||
}
|
||||
|
||||
func (s Value) Raw() any {
|
||||
return s.Val
|
||||
}
|
||||
|
||||
func (s Value) Time() time.Time {
|
||||
v, _ := s.ParseTime()
|
||||
|
||||
@@ -73,20 +78,11 @@ func (s Value) Time() time.Time {
|
||||
}
|
||||
|
||||
func (s Value) Unmarshal(target any) error {
|
||||
if v, ok := s.Raw().([]byte); ok {
|
||||
err := json.Unmarshal(v, target)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %w", config.ErrInvalidValue, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return config.ErrInvalidValue
|
||||
return typeAssert(s.Val, target)
|
||||
}
|
||||
|
||||
func (s Value) ParseInt() (int, error) {
|
||||
if r, ok := s.Raw().(int); ok {
|
||||
if r, ok := s.Any().(int); ok {
|
||||
return r, nil
|
||||
}
|
||||
|
||||
@@ -94,7 +90,7 @@ func (s Value) ParseInt() (int, error) {
|
||||
}
|
||||
|
||||
func (s Value) ParseInt64() (int64, error) {
|
||||
if r, ok := s.Raw().(int64); ok {
|
||||
if r, ok := s.Any().(int64); ok {
|
||||
return r, nil
|
||||
}
|
||||
|
||||
@@ -102,7 +98,7 @@ func (s Value) ParseInt64() (int64, error) {
|
||||
}
|
||||
|
||||
func (s Value) ParseUint() (uint, error) {
|
||||
if r, ok := s.Raw().(uint); ok {
|
||||
if r, ok := s.Any().(uint); ok {
|
||||
return r, nil
|
||||
}
|
||||
|
||||
@@ -110,7 +106,7 @@ func (s Value) ParseUint() (uint, error) {
|
||||
}
|
||||
|
||||
func (s Value) ParseUint64() (uint64, error) {
|
||||
if r, ok := s.Raw().(uint64); ok {
|
||||
if r, ok := s.Any().(uint64); ok {
|
||||
return r, nil
|
||||
}
|
||||
|
||||
@@ -118,7 +114,7 @@ func (s Value) ParseUint64() (uint64, error) {
|
||||
}
|
||||
|
||||
func (s Value) ParseFloat64() (float64, error) {
|
||||
if r, ok := s.Raw().(float64); ok {
|
||||
if r, ok := s.Any().(float64); ok {
|
||||
return r, nil
|
||||
}
|
||||
|
||||
@@ -126,7 +122,7 @@ func (s Value) ParseFloat64() (float64, error) {
|
||||
}
|
||||
|
||||
func (s Value) ParseString() (string, error) {
|
||||
if r, ok := s.Raw().(string); ok {
|
||||
if r, ok := s.Any().(string); ok {
|
||||
return r, nil
|
||||
}
|
||||
|
||||
@@ -134,7 +130,7 @@ func (s Value) ParseString() (string, error) {
|
||||
}
|
||||
|
||||
func (s Value) ParseBool() (bool, error) {
|
||||
if b, ok := s.Raw().(bool); ok {
|
||||
if b, ok := s.Any().(bool); ok {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
@@ -142,7 +138,7 @@ func (s Value) ParseBool() (bool, error) {
|
||||
}
|
||||
|
||||
func (s Value) ParseDuration() (time.Duration, error) {
|
||||
if b, ok := s.Raw().(time.Duration); ok {
|
||||
if b, ok := s.Any().(time.Duration); ok {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
@@ -150,7 +146,7 @@ func (s Value) ParseDuration() (time.Duration, error) {
|
||||
}
|
||||
|
||||
func (s Value) ParseTime() (time.Time, error) {
|
||||
if b, ok := s.Raw().(time.Time); ok {
|
||||
if b, ok := s.Any().(time.Time); ok {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
@@ -158,5 +154,100 @@ func (s Value) ParseTime() (time.Time, error) {
|
||||
}
|
||||
|
||||
func (s Value) IsEquals(in config.Value) bool {
|
||||
return s.String() == in.String()
|
||||
return s.Any() == in.Any()
|
||||
}
|
||||
|
||||
func (s Value) Any() any {
|
||||
return s.Val
|
||||
}
|
||||
|
||||
func typeAssert(source, target any) error {
|
||||
if source == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if directTypeAssert(source, target) {
|
||||
return nil
|
||||
}
|
||||
|
||||
valTarget := reflect.ValueOf(target)
|
||||
if !valTarget.IsValid() || valTarget.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("ptr target:%w", config.ErrInvalidValue)
|
||||
}
|
||||
|
||||
valTarget = valTarget.Elem()
|
||||
|
||||
if !valTarget.IsValid() {
|
||||
return fmt.Errorf("elem targer:%w", config.ErrInvalidValue)
|
||||
}
|
||||
|
||||
valSource := reflect.ValueOf(source)
|
||||
if !valSource.IsValid() {
|
||||
return fmt.Errorf("source:%w", config.ErrInvalidValue)
|
||||
}
|
||||
|
||||
valSource = deReference(valSource)
|
||||
if err := canSet(valSource, valTarget); err != nil {
|
||||
return fmt.Errorf("can set:%w", err)
|
||||
}
|
||||
|
||||
valTarget.Set(valSource)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func canSet(source, target reflect.Value) error {
|
||||
if source.Kind() != target.Kind() {
|
||||
return fmt.Errorf("source=%v target=%v:%w", source.Kind(), target.Kind(), config.ErrInvalidValue)
|
||||
}
|
||||
|
||||
if source.Kind() == reflect.Slice && source.Type().Elem().Kind() != target.Type().Elem().Kind() {
|
||||
return fmt.Errorf("slice source=%v, slice target=%v:%w",
|
||||
source.Type().Elem().Kind(), target.Type().Elem().Kind(), config.ErrInvalidValue)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func directTypeAssert(source, target any) bool {
|
||||
var ok bool
|
||||
|
||||
switch val := target.(type) {
|
||||
case *string:
|
||||
*val, ok = source.(string)
|
||||
case *[]byte:
|
||||
*val, ok = source.([]byte)
|
||||
case *int:
|
||||
*val, ok = source.(int)
|
||||
case *int64:
|
||||
*val, ok = source.(int64)
|
||||
case *uint:
|
||||
*val, ok = source.(uint)
|
||||
case *uint64:
|
||||
*val, ok = source.(uint64)
|
||||
case *bool:
|
||||
*val, ok = source.(bool)
|
||||
case *float64:
|
||||
*val, ok = source.(float64)
|
||||
case *time.Duration:
|
||||
*val, ok = source.(time.Duration)
|
||||
case *time.Time:
|
||||
*val, ok = source.(time.Time)
|
||||
case *[]string:
|
||||
*val, ok = source.([]string)
|
||||
case *map[string]string:
|
||||
*val, ok = source.(map[string]string)
|
||||
case *map[string]any:
|
||||
*val, ok = source.(map[string]any)
|
||||
}
|
||||
|
||||
return ok
|
||||
}
|
||||
|
||||
func deReference(v reflect.Value) reflect.Value {
|
||||
if (v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface) && !v.IsNil() {
|
||||
return v.Elem()
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user