1 module jcli.core.result; 2 3 struct ResultOf(alias T) 4 { 5 enum IsVoid = is(T == void); 6 alias This = typeof(this); 7 8 private 9 { 10 string _error = "I've not been initialised."; 11 static if(!IsVoid) 12 T _value; 13 } 14 15 static if(IsVoid) 16 { 17 static This ok()() 18 { 19 This t; 20 t._error = null; 21 return t; 22 } 23 } 24 else 25 { 26 static This ok()(T value) 27 { 28 This t; 29 t._error = null; 30 t._value = value; 31 return t; 32 } 33 } 34 35 static This fail()(string error) 36 { 37 This t; 38 t._error = error; 39 return t; 40 } 41 42 inout: 43 44 bool isOk()() 45 { 46 return this._error is null; 47 } 48 49 string error()() 50 { 51 assert(!this.isOk, "Cannot call .error on an ok result. Please use .isOk to check."); 52 return this._error; 53 } 54 55 static if(!IsVoid) 56 inout(T) value()() inout 57 { 58 assert(this.isOk, "Cannot call .value on a failed result. Please use .isOk to check."); 59 return this._value; 60 } 61 } 62 /// 63 unittest 64 { 65 auto ok = ResultOf!int.ok(1); 66 auto fail = ResultOf!int.fail("Bad"); 67 auto init = ResultOf!int.init; 68 auto void_ = Result.ok(); 69 70 assert(ok.isOk); 71 assert(ok.value == 1); 72 73 assert(!fail.isOk); 74 assert(fail.error == "Bad"); 75 76 assert(!init.isOk); 77 assert(init.error); 78 79 assert(void_.isOk); 80 } 81 82 alias Result = ResultOf!void; 83 84 auto ok(T)(T value) 85 { 86 return ResultOf!T.ok(value); 87 } 88 89 auto ok()() 90 { 91 return Result.ok(); 92 } 93 94 auto fail(T)(string error) 95 { 96 return ResultOf!T.fail(error); 97 }