(o *Object, dst reflect.Value, typ reflect.Type, ctx *objectExportCtx)
| 1023 | } |
| 1024 | |
| 1025 | func genericExportToArrayOrSlice(o *Object, dst reflect.Value, typ reflect.Type, ctx *objectExportCtx) (err error) { |
| 1026 | r := o.runtime |
| 1027 | |
| 1028 | if method := toMethod(r.getV(o, SymIterator)); method != nil { |
| 1029 | // iterable |
| 1030 | |
| 1031 | var values []Value |
| 1032 | // cannot change (append to) the slice once it's been put into the cache, so we need to know its length beforehand |
| 1033 | ex := r.try(func() { |
| 1034 | values = r.iterableToList(o, method) |
| 1035 | }) |
| 1036 | if ex != nil { |
| 1037 | return ex |
| 1038 | } |
| 1039 | if typ.Kind() == reflect.Array { |
| 1040 | if dst.Len() != len(values) { |
| 1041 | return fmt.Errorf("cannot convert an iterable into an array, lengths mismatch (have %d, need %d)", len(values), dst.Len()) |
| 1042 | } |
| 1043 | } else { |
| 1044 | dst.Set(reflect.MakeSlice(typ, len(values), len(values))) |
| 1045 | } |
| 1046 | ctx.putTyped(o, typ, dst.Interface()) |
| 1047 | for i, val := range values { |
| 1048 | err = r.toReflectValue(val, dst.Index(i), ctx) |
| 1049 | if err != nil { |
| 1050 | return |
| 1051 | } |
| 1052 | } |
| 1053 | } else { |
| 1054 | // array-like |
| 1055 | var lp Value |
| 1056 | if _, ok := o.self.assertCallable(); !ok { |
| 1057 | lp = o.self.getStr("length", nil) |
| 1058 | } |
| 1059 | if lp == nil { |
| 1060 | return fmt.Errorf("cannot convert %v to %v: not an array or iterable", o, typ) |
| 1061 | } |
| 1062 | l := toIntStrict(toLength(lp)) |
| 1063 | if dst.Len() != l { |
| 1064 | if typ.Kind() == reflect.Array { |
| 1065 | return fmt.Errorf("cannot convert an array-like object into an array, lengths mismatch (have %d, need %d)", l, dst.Len()) |
| 1066 | } else { |
| 1067 | dst.Set(reflect.MakeSlice(typ, l, l)) |
| 1068 | } |
| 1069 | } |
| 1070 | ctx.putTyped(o, typ, dst.Interface()) |
| 1071 | for i := 0; i < l; i++ { |
| 1072 | val := nilSafe(o.self.getIdx(valueInt(i), nil)) |
| 1073 | err = r.toReflectValue(val, dst.Index(i), ctx) |
| 1074 | if err != nil { |
| 1075 | return |
| 1076 | } |
| 1077 | } |
| 1078 | } |
| 1079 | |
| 1080 | return |
| 1081 | } |
| 1082 |
no test coverage detected
searching dependent graphs…