github.com/codingeasygo/util@v0.0.0-20231206062002-1ce2f004b7d9/xmap/wrap.go (about)

     1  package xmap
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"sync"
     7  )
     8  
     9  // Wrap will wrap raw map to safe
    10  func Wrap(v interface{}) (m M) {
    11  	if v == nil {
    12  		panic("v is nil")
    13  	}
    14  	if mval, ok := v.(M); ok {
    15  		m = mval
    16  	} else if mval, ok := v.(map[string]interface{}); ok {
    17  		m = M(mval)
    18  	} else if rm, ok := v.(RawMapable); ok {
    19  		m = M(rm.RawMap())
    20  	} else {
    21  		panic(fmt.Sprintf("not supported type %v", reflect.TypeOf(v)))
    22  	}
    23  	return
    24  }
    25  
    26  // WrapArray will wrap base values to array
    27  func WrapArray(v interface{}) (ms []M) {
    28  	if v == nil {
    29  		return nil
    30  	}
    31  	vals := reflect.ValueOf(v)
    32  	if vals.Kind() != reflect.Slice {
    33  		panic(fmt.Errorf("incompactable kind(%v)", vals.Kind()))
    34  	}
    35  	for i := 0; i < vals.Len(); i++ {
    36  		if vals.Index(i).IsZero() {
    37  			ms = append(ms, nil)
    38  		} else {
    39  			ms = append(ms, Wrap(vals.Index(i).Interface()))
    40  		}
    41  	}
    42  	return
    43  }
    44  
    45  // Parse will parse val to map
    46  func Parse(v interface{}) (m Valuable, err error) {
    47  	if v == nil {
    48  		err = fmt.Errorf("v is nil")
    49  		return
    50  	}
    51  	m, err = MapVal(v)
    52  	if err == nil {
    53  		return
    54  	}
    55  	err = nil
    56  	if val, ok := v.(Valuable); ok {
    57  		m = val
    58  	} else if base, ok := v.(BaseValuable); ok {
    59  		m = &impl{BaseValuable: base}
    60  	} else {
    61  		err = fmt.Errorf("not supported type %v", reflect.TypeOf(v))
    62  	}
    63  	return
    64  }
    65  
    66  // ParseArray will parse value to map array
    67  func ParseArray(v interface{}) (ms []Valuable, err error) {
    68  	if v == nil {
    69  		return
    70  	}
    71  	raws, err := ArrayMapVal(v)
    72  	if err == nil {
    73  		for _, raw := range raws {
    74  			ms = append(ms, raw)
    75  		}
    76  		return
    77  	}
    78  	err = nil
    79  	vals := reflect.ValueOf(v)
    80  	if vals.Kind() != reflect.Slice {
    81  		err = fmt.Errorf("incompactable kind(%v)", vals.Kind())
    82  		return
    83  	}
    84  	var m Valuable
    85  	for i := 0; i < vals.Len(); i++ {
    86  		if vals.Index(i).IsZero() {
    87  			m = nil
    88  		} else {
    89  			m, err = Parse(vals.Index(i).Interface())
    90  		}
    91  		if err != nil {
    92  			break
    93  		}
    94  		ms = append(ms, m)
    95  	}
    96  	return
    97  }
    98  
    99  // WrapSafe will wrap raw map to safe
   100  func WrapSafe(raw interface{}) (m *SafeM) {
   101  	if raw == nil {
   102  		panic("raw is nil")
   103  	}
   104  	var b BaseValuable
   105  	if m, ok := raw.(M); ok {
   106  		b = m
   107  	} else if base, ok := raw.(BaseValuable); ok {
   108  		b = base
   109  	} else if mval, ok := raw.(map[string]interface{}); ok {
   110  		b = M(mval)
   111  	} else if rm, ok := raw.(RawMapable); ok {
   112  		b = M(rm.RawMap())
   113  	} else {
   114  		panic("not supported type " + reflect.TypeOf(raw).Kind().String())
   115  	}
   116  	m = &SafeM{
   117  		raw:    b,
   118  		locker: sync.RWMutex{},
   119  	}
   120  	m.Valuable = &impl{BaseValuable: m}
   121  	return
   122  }
   123  
   124  // ParseSafe will parse val to map
   125  func ParseSafe(v interface{}) (m Valuable, err error) {
   126  	if v == nil {
   127  		err = fmt.Errorf("v is nil")
   128  		return
   129  	}
   130  	m, err = MapVal(v)
   131  	if err == nil {
   132  		m = WrapSafe(m)
   133  		return
   134  	}
   135  	err = nil
   136  	if base, ok := v.(BaseValuable); ok {
   137  		m = WrapSafe(base)
   138  	} else {
   139  		err = fmt.Errorf("not supported type %v", reflect.TypeOf(v))
   140  	}
   141  	return
   142  }
   143  
   144  // WrapSafeArray will wrap raw map to safe
   145  func WrapSafeArray(v interface{}) (ms []Valuable) {
   146  	if v == nil {
   147  		return nil
   148  	}
   149  	vals := reflect.ValueOf(v)
   150  	if vals.Kind() != reflect.Slice {
   151  		panic(fmt.Errorf("incompactable kind(%v)", vals.Kind()))
   152  	}
   153  	for i := 0; i < vals.Len(); i++ {
   154  		if vals.Index(i).IsZero() {
   155  			ms = append(ms, nil)
   156  		} else {
   157  			ms = append(ms, WrapSafe(vals.Index(i).Interface()))
   158  		}
   159  	}
   160  	return
   161  }
   162  
   163  // ParseSafeArray will parse value to map array
   164  func ParseSafeArray(v interface{}) (ms []Valuable, err error) {
   165  	if v == nil {
   166  		return
   167  	}
   168  	raws, err := ArrayMapVal(v)
   169  	if err == nil {
   170  		for _, raw := range raws {
   171  			ms = append(ms, WrapSafe(raw))
   172  		}
   173  		return
   174  	}
   175  	err = nil
   176  	vals := reflect.ValueOf(v)
   177  	if vals.Kind() != reflect.Slice {
   178  		err = fmt.Errorf("incompactable kind(%v)", vals.Kind())
   179  		return
   180  	}
   181  	var m Valuable
   182  	for i := 0; i < vals.Len(); i++ {
   183  		if vals.Index(i).IsZero() {
   184  			m = nil
   185  		} else {
   186  			m, err = ParseSafe(vals.Index(i).Interface())
   187  		}
   188  		if err != nil {
   189  			break
   190  		}
   191  		ms = append(ms, m)
   192  	}
   193  	return
   194  }