@@ -1695,80 +1695,92 @@ abstract Assertion(() -> Bool) {
16951695 }
16961696}
16971697
1698- // abstract Result<T>({ fn:haxe.Constraints.Function, args:Array<Dynamic> }) {
1699- // public inline function new(value:Dynamic) {
1700- // // Accepts:
1701- // // - { fn:Function, args:Array<Dynamic> }
1702- // // - Function (with no args)
1703- // // - { fn:Function, args:haxe.extern.Rest<Dynamic> }
1704- // // - Tuple: [Function, Array<Dynamic>]
1705- // // - Anything that has both 'fn' and 'args' fields
1706- // if (value == null) throw 'Result cannot be constructed with null value';
1707-
1708- // var fn:Dynamic = null;
1709- // var args:Array<Dynamic> = [];
1710-
1711- // if (Reflect.isFunction(value)) {
1712- // fn = value;
1713- // } else if (Std.isOfType(value, Array) && value.length == 2 && Reflect.isFunction(value[0])) {
1714- // fn = value[0];
1715- // args = value[1];
1716- // } else if (Reflect.hasField(value, "fn") && Reflect.isFunction(Reflect.field(value, "fn"))) {
1717- // fn = Reflect.field(value, "fn");
1718- // if (Reflect.hasField(value, "args")) {
1719- // args = Reflect.field(value, "args");
1720- // }
1721- // } else if (Reflect.hasField(value, "function") && Reflect.isFunction(Reflect.field(value, "function"))) {
1722- // fn = Reflect.field(value, "function");
1723- // if (Reflect.hasField(value, "arguments")) {
1724- // args = Reflect.field(value, "arguments");
1725- // }
1726- // } else {
1727- // throw 'Result: value must be a function, or an object/array with function and arguments';
1728- // }
1698+ /**
1699+ * Result<T, E> is an abstract type representing either a successful result of type T or an error of type E.
1700+ * It can be implicitly cast to T, but will throw an error if the Result is an error.
1701+ */
1702+ private enum ResultData < T , E > {
1703+ Ok (value :T );
1704+ Err (error :E );
1705+ }
17291706
1730- // this = { fn: fn, args: args };
1731- // }
1707+ abstract Result < T , E > (ResultData < T , E > ) {
1708+ public inline function new (value : ResultData <T , E >) {
1709+ this = value ;
1710+ }
17321711
1733- // // Whenever this is accessed, run the function with the arguments
1734- // @:to
1735- // public inline function toValue():T {
1736- // var fn = Reflect.field(this, "fn");
1737- // var args = Reflect.field(this, "args");
1738- // return Reflect.callMethod(null, fn, args);
1739- // }
1712+ public static inline function ok <T , E >(value : T ): Result <T , E > {
1713+ return new Result (Ok (value ));
1714+ }
17401715
1741- // @:from
1742- // public static inline function fromValue<T>(value:T):Result<T> {
1743- // return new Result(value);
1744- // }
1716+ public static inline function err <T , E >(error : E ): Result <T , E > {
1717+ return new Result (Err (error ));
1718+ }
17451719
1746- // @:to
1747- // public inline function toDynamic():Dynamic {
1748- // return this ;
1749- // }
1720+ @ :from
1721+ public static inline function fromReturn < T , E >( v : T ) : Result < T , E > {
1722+ return ok ( v ) ;
1723+ }
17501724
1751- // // Field access triggers function call
1752- // @:op(a.b)
1753- // public inline function opFieldAccessGet(field:String):Dynamic {
1754- // return this.fn();
1755- // }
1725+ @:from
1726+ public static inline function fromThrow <T , E >(e : E ): Result <T , E > {
1727+ return err (e );
1728+ }
17561729
1757- // // Array access triggers function call
1758- // @:arrayAccess
1759- // public inline function arrayRead(idx:Dynamic):Dynamic {
1760- // return this.fn();
1761- // }
1730+ @:from
1731+ public static inline function fromOk <T , E >(value : T ): Result <T , E > {
1732+ return ok (value );
1733+ }
17621734
1763- // // Call operator triggers function call (with optional override args)
1764- // @:op(a())
1765- // public inline function opCall(args:haxe.extern.Rest<Dynamic>):Dynamic {
1766- // var fn = Reflect.field(this, "fn");
1767- // var origArgs = Reflect.field(this, "args");
1768- // var callArgs = (args.length > 0) ? args : origArgs;
1769- // return Reflect.callMethod(null, fn, callArgs);
1770- // }
1771- // }
1735+ @:from
1736+ public static inline function fromErr <T , E >(error : E ): Result <T , E > {
1737+ return err (error );
1738+ }
1739+
1740+ @:to
1741+ public inline function toValue (): T {
1742+ return switch (this ) {
1743+ case Ok (v ): v ;
1744+ case Err (e ): throw ' Result: Attempted to access value, but was error: ' + Std .string (e );
1745+ }
1746+ }
1747+
1748+ public inline function isOk (): Bool {
1749+ return switch (this ) {
1750+ case Ok (_ ): true ;
1751+ case Err (_ ): false ;
1752+ }
1753+ }
1754+
1755+ public inline function isErr (): Bool {
1756+ return ! isOk ();
1757+ }
1758+
1759+ public inline function unwrap (): T {
1760+ return this ;
1761+ }
1762+
1763+ public inline function unwrapErr (): E {
1764+ return switch (this ) {
1765+ case Ok (_ ): throw ' Result: Attempted to access error, but was Ok' ;
1766+ case Err (e ): e ;
1767+ }
1768+ }
1769+
1770+ public inline function map <U >(f : T -> U ): Result <U , E > {
1771+ return switch (this ) {
1772+ case Ok (v ): Result .ok (f (v ));
1773+ case Err (e ): Result .err (e );
1774+ }
1775+ }
1776+
1777+ public inline function mapErr <F >(f : E -> F ): Result <T , F > {
1778+ return switch (this ) {
1779+ case Ok (v ): Result .ok (v );
1780+ case Err (e ): Result .err (f (e ));
1781+ }
1782+ }
1783+ }
17721784
17731785abstract Immutable < T > (Dynamic ) {
17741786 public inline function new (value : Dynamic ) {
@@ -2489,4 +2501,4 @@ abstract FieldAccTest<T>(Dynamic) {
24892501 trace (' opFieldAccess set: ' + field + ' = ' + value );
24902502 return value ;
24912503 }
2492- }
2504+ }
0 commit comments