(from super.Value, to super.Type)
| 145 | } |
| 146 | |
| 147 | func (c *cast) toArrayOrSet(from super.Value, to super.Type) (super.Value, bool) { |
| 148 | fromInner := super.InnerType(from.Type()) |
| 149 | toInner := super.InnerType(to) |
| 150 | if fromInner == nil { |
| 151 | // XXX Should also return an error if casting from fromInner to |
| 152 | // toInner will always fail. |
| 153 | return c.error(from, to) |
| 154 | } |
| 155 | types := map[super.Type]struct{}{} |
| 156 | var vals []super.Value |
| 157 | aok := true |
| 158 | for it := from.ContainerIter(); !it.Done(); { |
| 159 | val, ok := c.castNext(&it, fromInner, toInner) |
| 160 | aok = aok && ok |
| 161 | types[val.Type()] = struct{}{} |
| 162 | vals = append(vals, val) |
| 163 | } |
| 164 | if len(vals) == 0 { |
| 165 | return super.NewValue(to, from.Bytes()), aok |
| 166 | } |
| 167 | inner, ok := c.maybeConvertToUnion(vals, types) |
| 168 | aok = aok && ok |
| 169 | if inner != toInner { |
| 170 | if to.Kind() == super.ArrayKind { |
| 171 | to = c.sctx.LookupTypeArray(inner) |
| 172 | } else { |
| 173 | to = c.sctx.LookupTypeSet(inner) |
| 174 | } |
| 175 | } |
| 176 | var bytes scode.Bytes |
| 177 | for _, val := range vals { |
| 178 | bytes = scode.Append(bytes, val.Bytes()) |
| 179 | } |
| 180 | if to.Kind() == super.SetKind { |
| 181 | bytes = super.NormalizeSet(bytes) |
| 182 | } |
| 183 | return super.NewValue(to, bytes), aok |
| 184 | } |
| 185 | |
| 186 | func (c *cast) castNext(it *scode.Iter, from, to super.Type) (super.Value, bool) { |
| 187 | val := super.NewValue(from, it.Next()) |
no test coverage detected