github.com/keysonzzz/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgType/util.go (about)

     1  package kmgType
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"strconv"
     7  )
     8  
     9  func arrayGetSubValueByString(v reflect.Value, k string) (reflect.Value, error) {
    10  	i, err := arrayParseKey(v, k)
    11  	if err != nil {
    12  		return reflect.Value{}, nil
    13  	}
    14  	return v.Index(i), nil
    15  }
    16  func arrayParseKey(v reflect.Value, k string) (int, error) {
    17  	i64, err := strconv.ParseInt(k, 10, 64)
    18  	if err != nil {
    19  		return 0, fmt.Errorf("[arrayParseKey] index is not int k:%s", k)
    20  	}
    21  	i := int(i64)
    22  	if i >= v.Len() || i < 0 {
    23  		return 0, fmt.Errorf("[arrayParseKey] index is not of range k:%s,len:%d", k, v.Len())
    24  	}
    25  	return i, nil
    26  }
    27  
    28  type saveScaleFromStringer struct {
    29  	SaveScaleInterface
    30  	ReflectTypeGetter
    31  }
    32  
    33  func (t saveScaleFromStringer) FromString(value string) (reflect.Value, error) {
    34  	rv := reflect.New(t.GetReflectType()).Elem()
    35  	err := t.SaveScale(rv, value)
    36  	if err != nil {
    37  		return reflect.Value{}, err
    38  	}
    39  	return rv, nil
    40  }
    41  
    42  type reflectTypeGetterImp struct {
    43  	reflect.Type
    44  }
    45  
    46  func (t reflectTypeGetterImp) GetReflectType() reflect.Type {
    47  	return t.Type
    48  }
    49  
    50  type saveScaleEditabler struct {
    51  	SaveScaleInterface
    52  	ReflectTypeGetter
    53  }
    54  
    55  func (t saveScaleEditabler) SaveByPath(v *reflect.Value, path Path, value string) (err error) {
    56  	if len(path) != 0 {
    57  		return fmt.Errorf("[saveScaleEditabler.Save] get string with some path,path:%s type:%s", path, v.Type().Kind())
    58  	}
    59  	if !v.CanSet() {
    60  		*v = reflect.New(t.GetReflectType()).Elem()
    61  	}
    62  	return t.SaveScale(*v, value)
    63  }
    64  
    65  func (t saveScaleEditabler) DeleteByPath(v *reflect.Value, path Path) (err error) {
    66  	return fmt.Errorf("[saveScaleEditabler.Delete] scale type can not delete,path:%s type:%s", path, v.Type().Kind())
    67  }
    68  
    69  type getElemByStringEditorabler struct {
    70  	GetElemByStringInterface
    71  	ReflectTypeGetter
    72  }
    73  
    74  func (t getElemByStringEditorabler) SaveByPath(v *reflect.Value, path Path, value string) (err error) {
    75  	if len(path) == 0 {
    76  		return nil
    77  	}
    78  	ev, et, err := t.GetElemByString(*v, path[0])
    79  	if err != nil {
    80  		return err
    81  	}
    82  	oEv := ev
    83  	err = et.SaveByPath(&oEv, path[1:], value)
    84  	if err != nil {
    85  		return err
    86  	}
    87  
    88  	//not change this type
    89  	if oEv == ev {
    90  		return nil
    91  	}
    92  	if v.CanSet() {
    93  		return nil
    94  	}
    95  	output := reflect.New(t.GetReflectType()).Elem()
    96  	output.Set(*v)
    97  	*v = output
    98  	ev, _, err = t.GetElemByString(*v, path[0])
    99  	if err != nil {
   100  		return err
   101  	}
   102  	ev.Set(oEv)
   103  	return nil
   104  }
   105  
   106  /*
   107  func (t getElemByStringEditorabler) DeleteByPath(v *reflect.Value, path Path) (err error) {
   108  
   109  }
   110  */
   111  //can not pass through map
   112  func passThougthDeleteByPath(t GetElemByStringAndReflectTypeGetterInterface, v *reflect.Value, path Path) (err error) {
   113  	ev, et, err := t.GetElemByString(*v, path[0])
   114  	if err != nil {
   115  		return err
   116  	}
   117  	oEv := ev
   118  	err = et.DeleteByPath(&oEv, path[1:])
   119  	if err != nil {
   120  		return err
   121  	}
   122  	if oEv == ev {
   123  		return
   124  	}
   125  	if v.CanSet() {
   126  		return
   127  	}
   128  	output := reflect.New(t.GetReflectType()).Elem()
   129  	output.Set(*v)
   130  	*v = output
   131  	ev, _, err = t.GetElemByString(*v, path[0])
   132  	if err != nil {
   133  		return err
   134  	}
   135  	ev.Set(oEv)
   136  	return nil
   137  }