summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/d5/tengo/objects/conversion.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/d5/tengo/objects/conversion.go')
-rw-r--r--vendor/github.com/d5/tengo/objects/conversion.go249
1 files changed, 249 insertions, 0 deletions
diff --git a/vendor/github.com/d5/tengo/objects/conversion.go b/vendor/github.com/d5/tengo/objects/conversion.go
new file mode 100644
index 00000000..3c17546f
--- /dev/null
+++ b/vendor/github.com/d5/tengo/objects/conversion.go
@@ -0,0 +1,249 @@
+package objects
+
+import (
+ "fmt"
+ "strconv"
+ "time"
+)
+
+// ToString will try to convert object o to string value.
+func ToString(o Object) (v string, ok bool) {
+ if o == UndefinedValue {
+ //ok = false
+ return
+ }
+
+ ok = true
+
+ if str, isStr := o.(*String); isStr {
+ v = str.Value
+ } else {
+ v = o.String()
+ }
+
+ return
+}
+
+// ToInt will try to convert object o to int value.
+func ToInt(o Object) (v int, ok bool) {
+ switch o := o.(type) {
+ case *Int:
+ v = int(o.Value)
+ ok = true
+ case *Float:
+ v = int(o.Value)
+ ok = true
+ case *Char:
+ v = int(o.Value)
+ ok = true
+ case *Bool:
+ if o == TrueValue {
+ v = 1
+ }
+ ok = true
+ case *String:
+ c, err := strconv.ParseInt(o.Value, 10, 64)
+ if err == nil {
+ v = int(c)
+ ok = true
+ }
+ }
+
+ //ok = false
+ return
+}
+
+// ToInt64 will try to convert object o to int64 value.
+func ToInt64(o Object) (v int64, ok bool) {
+ switch o := o.(type) {
+ case *Int:
+ v = o.Value
+ ok = true
+ case *Float:
+ v = int64(o.Value)
+ ok = true
+ case *Char:
+ v = int64(o.Value)
+ ok = true
+ case *Bool:
+ if o == TrueValue {
+ v = 1
+ }
+ ok = true
+ case *String:
+ c, err := strconv.ParseInt(o.Value, 10, 64)
+ if err == nil {
+ v = c
+ ok = true
+ }
+ }
+
+ //ok = false
+ return
+}
+
+// ToFloat64 will try to convert object o to float64 value.
+func ToFloat64(o Object) (v float64, ok bool) {
+ switch o := o.(type) {
+ case *Int:
+ v = float64(o.Value)
+ ok = true
+ case *Float:
+ v = o.Value
+ ok = true
+ case *String:
+ c, err := strconv.ParseFloat(o.Value, 64)
+ if err == nil {
+ v = c
+ ok = true
+ }
+ }
+
+ //ok = false
+ return
+}
+
+// ToBool will try to convert object o to bool value.
+func ToBool(o Object) (v bool, ok bool) {
+ ok = true
+ v = !o.IsFalsy()
+
+ return
+}
+
+// ToRune will try to convert object o to rune value.
+func ToRune(o Object) (v rune, ok bool) {
+ switch o := o.(type) {
+ case *Int:
+ v = rune(o.Value)
+ ok = true
+ case *Char:
+ v = rune(o.Value)
+ ok = true
+ }
+
+ //ok = false
+ return
+}
+
+// ToByteSlice will try to convert object o to []byte value.
+func ToByteSlice(o Object) (v []byte, ok bool) {
+ switch o := o.(type) {
+ case *Bytes:
+ v = o.Value
+ ok = true
+ case *String:
+ v = []byte(o.Value)
+ ok = true
+ }
+
+ //ok = false
+ return
+}
+
+// ToTime will try to convert object o to time.Time value.
+func ToTime(o Object) (v time.Time, ok bool) {
+ switch o := o.(type) {
+ case *Time:
+ v = o.Value
+ ok = true
+ case *Int:
+ v = time.Unix(o.Value, 0)
+ ok = true
+ }
+
+ //ok = false
+ return
+}
+
+// objectToInterface attempts to convert an object o to an interface{} value
+func objectToInterface(o Object) (res interface{}) {
+ switch o := o.(type) {
+ case *Int:
+ res = o.Value
+ case *String:
+ res = o.Value
+ case *Float:
+ res = o.Value
+ case *Bool:
+ res = o == TrueValue
+ case *Char:
+ res = o.Value
+ case *Bytes:
+ res = o.Value
+ case *Array:
+ res = make([]interface{}, len(o.Value))
+ for i, val := range o.Value {
+ res.([]interface{})[i] = objectToInterface(val)
+ }
+ case *Map:
+ res = make(map[string]interface{})
+ for key, v := range o.Value {
+ res.(map[string]interface{})[key] = objectToInterface(v)
+ }
+ case Object:
+ return o
+ }
+
+ return
+}
+
+// FromInterface will attempt to convert an interface{} v to a Tengo Object
+func FromInterface(v interface{}) (Object, error) {
+ switch v := v.(type) {
+ case nil:
+ return UndefinedValue, nil
+ case string:
+ return &String{Value: v}, nil
+ case int64:
+ return &Int{Value: v}, nil
+ case int:
+ return &Int{Value: int64(v)}, nil
+ case bool:
+ if v {
+ return TrueValue, nil
+ }
+ return FalseValue, nil
+ case rune:
+ return &Char{Value: v}, nil
+ case byte:
+ return &Char{Value: rune(v)}, nil
+ case float64:
+ return &Float{Value: v}, nil
+ case []byte:
+ return &Bytes{Value: v}, nil
+ case error:
+ return &Error{Value: &String{Value: v.Error()}}, nil
+ case map[string]Object:
+ return &Map{Value: v}, nil
+ case map[string]interface{}:
+ kv := make(map[string]Object)
+ for vk, vv := range v {
+ vo, err := FromInterface(vv)
+ if err != nil {
+ return nil, err
+ }
+ kv[vk] = vo
+ }
+ return &Map{Value: kv}, nil
+ case []Object:
+ return &Array{Value: v}, nil
+ case []interface{}:
+ arr := make([]Object, len(v), len(v))
+ for i, e := range v {
+ vo, err := FromInterface(e)
+ if err != nil {
+ return nil, err
+ }
+
+ arr[i] = vo
+ }
+ return &Array{Value: arr}, nil
+ case time.Time:
+ return &Time{Value: v}, nil
+ case Object:
+ return v, nil
+ }
+
+ return nil, fmt.Errorf("cannot convert to object: %T", v)
+}