github.com/lingyao2333/mo-zero@v1.4.1/core/mapping/valuer.go (about)

     1  package mapping
     2  
     3  type (
     4  	// A Valuer interface defines the way to get values from the underlying object with keys.
     5  	Valuer interface {
     6  		// Value gets the value associated with the given key.
     7  		Value(key string) (interface{}, bool)
     8  	}
     9  
    10  	// A valuerWithParent defines a node that has a parent node.
    11  	valuerWithParent interface {
    12  		Valuer
    13  		// Parent get the parent valuer for current node.
    14  		Parent() valuerWithParent
    15  	}
    16  
    17  	// A node is a map that can use Value method to get values with given keys.
    18  	node struct {
    19  		current Valuer
    20  		parent  valuerWithParent
    21  	}
    22  
    23  	// A valueWithParent is used to wrap the value with its parent.
    24  	valueWithParent struct {
    25  		value  interface{}
    26  		parent valuerWithParent
    27  	}
    28  
    29  	// mapValuer is a type for map to meet the Valuer interface.
    30  	mapValuer map[string]interface{}
    31  	// simpleValuer is a type to get value from current node.
    32  	simpleValuer node
    33  	// recursiveValuer is a type to get the value recursively from current and parent nodes.
    34  	recursiveValuer node
    35  )
    36  
    37  // Value gets the value assciated with the given key from mv.
    38  func (mv mapValuer) Value(key string) (interface{}, bool) {
    39  	v, ok := mv[key]
    40  	return v, ok
    41  }
    42  
    43  // Value gets the value associated with the given key from sv.
    44  func (sv simpleValuer) Value(key string) (interface{}, bool) {
    45  	v, ok := sv.current.Value(key)
    46  	return v, ok
    47  }
    48  
    49  // Parent get the parent valuer from sv.
    50  func (sv simpleValuer) Parent() valuerWithParent {
    51  	if sv.parent == nil {
    52  		return nil
    53  	}
    54  
    55  	return recursiveValuer{
    56  		current: sv.parent,
    57  		parent:  sv.parent.Parent(),
    58  	}
    59  }
    60  
    61  // Value gets the value associated with the given key from rv,
    62  // and it will inherit the value from parent nodes.
    63  func (rv recursiveValuer) Value(key string) (interface{}, bool) {
    64  	val, ok := rv.current.Value(key)
    65  	if !ok {
    66  		if parent := rv.Parent(); parent != nil {
    67  			return parent.Value(key)
    68  		}
    69  
    70  		return nil, false
    71  	}
    72  
    73  	vm, ok := val.(map[string]interface{})
    74  	if !ok {
    75  		return val, true
    76  	}
    77  
    78  	parent := rv.Parent()
    79  	if parent == nil {
    80  		return val, true
    81  	}
    82  
    83  	pv, ok := parent.Value(key)
    84  	if !ok {
    85  		return val, true
    86  	}
    87  
    88  	pm, ok := pv.(map[string]interface{})
    89  	if !ok {
    90  		return val, true
    91  	}
    92  
    93  	for k, v := range pm {
    94  		if _, ok := vm[k]; !ok {
    95  			vm[k] = v
    96  		}
    97  	}
    98  
    99  	return vm, true
   100  }
   101  
   102  // Parent get the parent valuer from rv.
   103  func (rv recursiveValuer) Parent() valuerWithParent {
   104  	if rv.parent == nil {
   105  		return nil
   106  	}
   107  
   108  	return recursiveValuer{
   109  		current: rv.parent,
   110  		parent:  rv.parent.Parent(),
   111  	}
   112  }