github.com/vektra/tachyon@v0.0.0-20150921164542-0da4f3861aef/scope.go (about)

     1  package tachyon
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  )
     7  
     8  type Value interface {
     9  	Read() interface{}
    10  }
    11  
    12  type AnyValue struct {
    13  	v interface{}
    14  }
    15  
    16  func (a AnyValue) Read() interface{} {
    17  	return a.v
    18  }
    19  
    20  type AnyMap struct {
    21  	m map[interface{}]interface{}
    22  }
    23  
    24  func (a AnyMap) Read() interface{} {
    25  	return a.m
    26  }
    27  
    28  func (a AnyMap) Get(key string) (Value, bool) {
    29  	if v, ok := a.m[key]; ok {
    30  		return Any(v), true
    31  	}
    32  
    33  	return nil, false
    34  }
    35  
    36  type StrMap struct {
    37  	m map[string]interface{}
    38  }
    39  
    40  func (a StrMap) Get(key string) (Value, bool) {
    41  	if v, ok := a.m[key]; ok {
    42  		return Any(v), true
    43  	}
    44  
    45  	return nil, false
    46  }
    47  
    48  func (a StrMap) Read() interface{} {
    49  	return a.m
    50  }
    51  
    52  func (a AnyValue) MarshalJSON() ([]byte, error) {
    53  	return json.Marshal(a.v)
    54  }
    55  
    56  func (a AnyMap) MarshalJSON() ([]byte, error) {
    57  	return json.Marshal(a.m)
    58  }
    59  
    60  func (a StrMap) MarshalJSON() ([]byte, error) {
    61  	return json.Marshal(a.m)
    62  }
    63  
    64  func Any(v interface{}) Value {
    65  	switch sv := v.(type) {
    66  	case AnyValue:
    67  		return sv
    68  	case map[interface{}]interface{}:
    69  		return AnyMap{sv}
    70  	case map[string]interface{}:
    71  		return StrMap{sv}
    72  	default:
    73  		return AnyValue{v}
    74  	}
    75  }
    76  
    77  func (a AnyValue) GetYAML() (string, interface{}) {
    78  	return "", a.v
    79  }
    80  
    81  func (a AnyValue) SetYAML(tag string, v interface{}) bool {
    82  	a.v = v
    83  	return true
    84  }
    85  
    86  type Map interface {
    87  	Get(key string) (Value, bool)
    88  }
    89  
    90  type Scope interface {
    91  	Get(key string) (Value, bool)
    92  	Set(key string, val interface{})
    93  }
    94  
    95  type ScopeGetter interface {
    96  	Get(key string) (Value, bool)
    97  }
    98  
    99  func SV(v interface{}, ok bool) interface{} {
   100  	if !ok {
   101  		return nil
   102  	}
   103  
   104  	return v
   105  }
   106  
   107  type NestedScope struct {
   108  	Scope Scope
   109  	Vars  Vars
   110  }
   111  
   112  func NewNestedScope(parent Scope) *NestedScope {
   113  	return &NestedScope{parent, make(Vars)}
   114  }
   115  
   116  func SpliceOverrides(cur Scope, override *NestedScope) *NestedScope {
   117  	ns := NewNestedScope(cur)
   118  
   119  	for k, v := range override.Vars {
   120  		ns.Set(k, v)
   121  	}
   122  
   123  	return ns
   124  }
   125  
   126  func (n *NestedScope) Get(key string) (v Value, ok bool) {
   127  	v, ok = n.Vars[key]
   128  	if !ok && n.Scope != nil {
   129  		v, ok = n.Scope.Get(key)
   130  	}
   131  
   132  	return
   133  }
   134  
   135  func (n *NestedScope) Set(key string, v interface{}) {
   136  	n.Vars[key] = Any(v)
   137  }
   138  
   139  func (n *NestedScope) Empty() bool {
   140  	return len(n.Vars) == 0
   141  }
   142  
   143  func (n *NestedScope) Flatten() Scope {
   144  	if len(n.Vars) == 0 && n.Scope != nil {
   145  		return n.Scope
   146  	}
   147  
   148  	return n
   149  }
   150  
   151  func (n *NestedScope) addMapVars(mv map[interface{}]interface{}) error {
   152  	for k, v := range mv {
   153  		if sk, ok := k.(string); ok {
   154  			if sv, ok := v.(string); ok {
   155  				var err error
   156  
   157  				v, err = ExpandVars(n, sv)
   158  				if err != nil {
   159  					return err
   160  				}
   161  			}
   162  
   163  			n.Set(sk, v)
   164  		}
   165  	}
   166  
   167  	return nil
   168  }
   169  
   170  func (n *NestedScope) addVars(vars interface{}) (err error) {
   171  	switch mv := vars.(type) {
   172  	case map[interface{}]interface{}:
   173  		err = n.addMapVars(mv)
   174  	case []interface{}:
   175  		for _, i := range mv {
   176  			err = n.addVars(i)
   177  			if err != nil {
   178  				return
   179  			}
   180  		}
   181  	}
   182  
   183  	return
   184  }
   185  
   186  func ImportVarsFile(s Scope, path string) error {
   187  	var fv map[string]string
   188  
   189  	err := yamlFile(path, &fv)
   190  
   191  	if err != nil {
   192  		return err
   193  	}
   194  
   195  	for k, v := range fv {
   196  		s.Set(k, inferString(v))
   197  	}
   198  
   199  	return nil
   200  }
   201  
   202  func DisplayScope(s Scope) {
   203  	if ns, ok := s.(*NestedScope); ok {
   204  		DisplayScope(ns.Scope)
   205  
   206  		for k, v := range ns.Vars {
   207  			fmt.Printf("%s: %v\n", k, v)
   208  		}
   209  	}
   210  }