update client

This commit is contained in:
2025-12-26 14:23:54 +03:00
parent f4962e54a3
commit a5659c5d02
75 changed files with 2436 additions and 288 deletions

View File

@@ -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
}