Search code examples
castinghaxeopenflint64

Casting Int to Int64 in Haxe


When I set up primitive Int type to the Int64 it works fine. I even can catch a constructor method in supplementary class ___Int64 that accepts two Int values -- high and low. It seems that this casting is static and even such code works perfectly:

var short:Int = 1111;
var long:Int64 = 2222;
long = short;
trace(long.high, long.low); // =0,1111

But when I'm setting up value from a field of openfl.utils.Object instance like:

var id:Int64 = data["id"];

where value of the "id" field either Int or Int64 -- I've got an error:

TypeError: Error #1034: Type Coercion failed: cannot convert 1111 to haxe._Int64.___Int64.

Of course I can check the type of the field and properly instantiate an Int64 from Int. But is there a neat solution to automate type casting?


Solution

  • You could use an abstract type with implicit casts from Dynamic (the return value of openfl.utils.Object's array access get) to abstract the check away.

    abstract AnyInt64(Int64) from Int64 to Int64 {
        @:from static function fromDynamic(d:Dynamic):AnyInt64 {
            if (Std.is(d, Int))
                return Int64.ofInt(cast d);
            if (Int64.is(d)) {
                var i:Int64 = cast d;
                return i;
            }
            throw "conversion error";
        }
    }
    

    Usage:

    var data = new openfl.utils.Object();
    
    data["int"] = 500;
    var id:AnyInt64 = data["int"];
    
    data["int64"] = Int64.make(1, 0);
    var id2:AnyInt64 = data["int64"];
    

    You would need to find a good way of dealing with attempted conversions that are not Int or Int64 though (unless you only use those two types). Using Null<Int64> as the underlying type for AnyInt64 + checking for null might work.