Hi all,

I've been using D for a week now to compare it to Rust as a replacement to C++. One thing I miss from Rust is https://doc.rust-lang.org/std/result/ and its companion https://doc.rust-lang.org/std/macro.try!.html

They make for some nice syntax so I had a go at recreating them in D (below): One thing I cant figure out/don't know if is possible is to have a type that takes "void" (see last unittest)

For example in Rust a can declare a Result of Result<(), ErrorType> however I'm struggling to find the same semantics in D. Of course I can just use a bool but I'd prefer not to.


Thank you for your time

Nik


Result type:

struct Result(T, E)
{       
        this(inout T result) inout
        {
                _result = result;
                _is_result = true;
        }

        this(inout E error) inout
        {
                _error = error;
                _is_result = false;
        }

        bool is_result() const pure nothrow @safe @property
        {
                return _is_result;
        }

        T result() const pure nothrow @safe @property
        {
                return _result;
        }

        bool is_error() const pure nothrow @safe @property
        {
                return !_is_result;
        }

        E error() const pure nothrow @safe @property
        {
                return _error;
        }
private:
        T _result;
        bool _is_result;
        E _error;
}

unittest
{
        auto result = Result!(int, string)(1);
        assert(result.is_result);
        assert(result.result == 1);
}

unittest
{
        auto result = Result!(int, string)("error");
        assert(result.is_error);
        assert(result.error == "error");
}

unittest
{
        auto result_1 = Result!(int, string)(1);
        auto result_2 = Result!(int, string)(1);
        assert(result_1 == result_2);
}

unittest
{
        auto result_1 = Result!(int, string)(1);
        auto result_2 = Result!(int, string)(2);
        assert(result_1 != result_2);
}

unittest
{
        auto result_1 = Result!(int, string)(1);
        auto result_2 = Result!(int, string)("error");
        assert(result_1 != result_2);
}

unittest
{
        auto result_1 = Result!(int, string)("error");
        auto result_2 = Result!(int, string)("error");
        assert(result_1 == result_2);
}

unittest
{
        auto result_1 = Result!(int, string)("an error");
        auto result_2 = Result!(int, string)("error");
        assert(result_1 != result_2);
}

unittest
{
        enum ErrorType{A_Error, B_Error}
        auto result = Result!(int, ErrorType)(ErrorType.A_Error);
        assert(result.error() == ErrorType.A_Error);
        auto result_2 = Result!(immutable(bool), ErrorType)(true);
        assert(result_2.result());

        Result!(immutable(bool), ErrorType) a_method()
        {
                return Result!(immutable(bool), ErrorType)(true);
        }
        assert(a_method().result());
}

unittest
{
        auto result_1 = Result!(bool, string)(true);
        assert(result_1.result);
}

//unittest
//{
//      auto result_1 = Result!(void, string)(void);
//      auto result_2 = Result!(void, string)(void);
//      assert(result_1.is_result);
//      assert(result_1 == result_2);
//}

Reply via email to