1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- package raymond
- import "reflect"
- // DataFrame represents a private data frame.
- //
- // Cf. private variables documentation at: http://handlebarsjs.com/block_helpers.html
- type DataFrame struct {
- parent *DataFrame
- data map[string]interface{}
- }
- // NewDataFrame instanciates a new private data frame.
- func NewDataFrame() *DataFrame {
- return &DataFrame{
- data: make(map[string]interface{}),
- }
- }
- // Copy instanciates a new private data frame with receiver as parent.
- func (p *DataFrame) Copy() *DataFrame {
- result := NewDataFrame()
- for k, v := range p.data {
- result.data[k] = v
- }
- result.parent = p
- return result
- }
- // newIterDataFrame instanciates a new private data frame with receiver as parent and with iteration data set (@index, @key, @first, @last)
- func (p *DataFrame) newIterDataFrame(length int, i int, key interface{}) *DataFrame {
- result := p.Copy()
- result.Set("index", i)
- result.Set("key", key)
- result.Set("first", i == 0)
- result.Set("last", i == length-1)
- return result
- }
- // Set sets a data value.
- func (p *DataFrame) Set(key string, val interface{}) {
- p.data[key] = val
- }
- // Get gets a data value.
- func (p *DataFrame) Get(key string) interface{} {
- return p.find([]string{key})
- }
- // find gets a deep data value
- //
- // @todo This is NOT consistent with the way we resolve data in template (cf. `evalDataPathExpression()`) ! FIX THAT !
- func (p *DataFrame) find(parts []string) interface{} {
- data := p.data
- for i, part := range parts {
- val := data[part]
- if val == nil {
- return nil
- }
- if i == len(parts)-1 {
- // found
- return val
- }
- valValue := reflect.ValueOf(val)
- if valValue.Kind() != reflect.Map {
- // not found
- return nil
- }
- // continue
- data = mapStringInterface(valValue)
- }
- // not found
- return nil
- }
- // mapStringInterface converts any `map` to `map[string]interface{}`
- func mapStringInterface(value reflect.Value) map[string]interface{} {
- result := make(map[string]interface{})
- for _, key := range value.MapKeys() {
- result[strValue(key)] = value.MapIndex(key).Interface()
- }
- return result
- }
|