github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/builtins/core/element/element.go (about) 1 package element 2 3 import ( 4 "errors" 5 "fmt" 6 "strconv" 7 "strings" 8 9 "github.com/lmorg/murex/lang" 10 "github.com/lmorg/murex/lang/types" 11 ) 12 13 func init() { 14 lang.DefineMethod("[[", element, types.Unmarshal, types.Marshal) 15 } 16 17 func element(p *lang.Process) (err error) { 18 defer func() { 19 if r := recover(); r != nil { 20 err = fmt.Errorf("panic caught, please report this to https://github.com/lmorg/murex/issues : %s", r) 21 } 22 }() 23 24 dt := p.Stdin.GetDataType() 25 26 if err := p.ErrIfNotAMethod(); err != nil { 27 return err 28 } 29 30 params := p.Parameters.StringArray() 31 32 switch len(params) { 33 case 0: 34 return errors.New("missing parameter. Requires nested index") 35 36 case 1: 37 if strings.HasSuffix(params[0], "]]") { 38 params[0] = params[0][0 : len(params[0])-2] 39 } else { 40 return fmt.Errorf("missing closing brackets, ` ]]`\nExpression: %s", p.Parameters.StringAll()) 41 } 42 43 case 2: 44 last := len(params) - 1 45 if strings.HasSuffix(params[last], "]]") { 46 if len(params[last]) != 2 { 47 return errors.New("too many parameters") 48 } 49 } else { 50 return fmt.Errorf("missing closing brackets, ` ]]`\nExpression: %s", p.Parameters.StringAll()) 51 } 52 53 default: 54 return errors.New("too many parameters") 55 } 56 57 obj, err := lang.UnmarshalData(p, dt) 58 if err != nil { 59 return err 60 } 61 62 obj, err = lang.ElementLookup(obj, params[0]) 63 if err != nil { 64 return err 65 } 66 67 switch v := obj.(type) { 68 case string: 69 p.Stdout.SetDataType(types.String) 70 _, err = p.Stdout.Write([]byte(v)) 71 case []byte: 72 p.Stdout.SetDataType(types.String) 73 _, err = p.Stdout.Write(v) 74 case int: 75 p.Stdout.SetDataType(types.Integer) 76 _, err = p.Stdout.Write([]byte(strconv.Itoa(v))) 77 case int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: 78 p.Stdout.SetDataType(types.Integer) 79 _, err = fmt.Fprint(p.Stdout, v) 80 case float32: 81 p.Stdout.SetDataType(types.Float) 82 _, err = p.Stdout.Write([]byte(types.FloatToString(float64(v)))) 83 case float64: 84 p.Stdout.SetDataType(types.Float) 85 _, err = p.Stdout.Write([]byte(types.FloatToString(v))) 86 case bool: 87 p.Stdout.SetDataType(types.Boolean) 88 if v { 89 _, err = p.Stdout.Write(types.TrueByte) 90 } else { 91 _, err = p.Stdout.Write(types.FalseByte) 92 } 93 default: 94 p.Stdout.SetDataType(dt) 95 b, err := lang.MarshalData(p, dt, obj) 96 if err != nil { 97 return err 98 } 99 _, err = p.Stdout.Write(b) 100 if err != nil { 101 return err 102 } 103 } 104 105 return err 106 }