ResT Structure

Result type which can be either of the two variants: Ok(value-of-T) or Err(error-message).

Definition

Namespace: Orx.Fun.Result
Assembly: Orx.Fun.Result (in Orx.Fun.Result.dll) Version: 1.3.0+344c8bdd6f720ccfb2d8db7c61b76cf02be18f5f
C#
public readonly struct Res<T> : IEquatable<Res<T>>
Inheritance
Object    ValueType    ResT
Implements
IEquatableResT

Type Parameters

T

[Missing <typeparam name="T"/> documentation for "T:Orx.Fun.Result.Res`1"]

Constructors

ResT Result type which can either be Ok(value) or Err. Parameterless ctor returns Ok(default(T)); better use OkT(T) or ErrT(String) to construct results by adding `using static OptRes.Ext`.

Properties

IsErr True if the result is Err; false otherwise.
IsOk True if the result is Ok; false otherwise.

Methods

And(FuncRes) Combines two results: this and other as follows:
  • returns this if both are Ok;
  • returns the error if one of the results is an Err;
  • returns the combined error if both results are Err.
C#
var combined = Ok(12).And(Ok());
Assert.Equal(Ok(12), combined);

combined = Ok(12).And(Err("failure"));
Assert.True(combined.IsErr);

combined = Err<int>("error").And(Ok());
Assert.True(combined.IsErr);

combined = Err<int>("error").And(Err("failure"));
Assert.True(combined.IsErr);
And(Res) Combines two results: this and other as follows:
  • returns this if both are Ok;
  • returns the error if one of the results is an Err;
  • returns the combined error if both results are Err.
C#
var combined = Ok(12).And(Ok());
Assert.Equal(Ok(12), combined);

combined = Ok(12).And(Err("failure"));
Assert.True(combined.IsErr);

combined = Err<int>("error").And(Ok());
Assert.True(combined.IsErr);

combined = Err<int>("error").And(Err("failure"));
Assert.True(combined.IsErr);
AndT2(FuncResT2) Combines two results: this and other as follows:
  • returns Ok of a tuple of both values if both results are Ok;
  • returns the error if one of the results is an Err;
  • returns the combined error if both results are Err.
C#
var combined = Ok(12).And(Ok(true));
Assert.Equal(Ok((12, true)), combined);

combined = Ok(12).And(Err<bool>("failure"));
Assert.True(combined.IsErr);

combined = Err<int>("error").And(Ok(true));
Assert.True(combined.IsErr);

combined = Err<int>("error").And(Err<bool>("failure"));
Assert.True(combined.IsErr);
AndT2(ResT2) Combines two results: this and other as follows:
  • returns Ok of a tuple of both values if both results are Ok;
  • returns the error if one of the results is an Err;
  • returns the combined error if both results are Err.
C#
var combined = Ok(12).And(Ok(true));
Assert.Equal(Ok((12, true)), combined);

combined = Ok(12).And(Err<bool>("failure"));
Assert.True(combined.IsErr);

combined = Err<int>("error").And(Ok(true));
Assert.True(combined.IsErr);

combined = Err<int>("error").And(Err<bool>("failure"));
Assert.True(combined.IsErr);
Do Runs action(Unwrap()) only if IsOk; and returns itself back.
C#
// the logging call will only be made if the result of TryGetUser is Ok of a user.
// Since Do returns back the result, it can still be assigned to var 'user'.
Res<User> user = TryGetUser().Do(u => Log.Info($"User '{u.Name}' grabbed"));
DoIfErr Runs actionOnErr() only if IsErr; and returns itself back. Counterpart of Do(ActionT) for the Err variant.
C#
// the logging call will only be made if the result of TryGetUser is Err.
// Since DoIfErr returns back the result, it can still be assigned to var 'user'.
Res<User> user = TryGetUser().DoIfErr(err => Log.Warning($"User could not be read. {err}"));
Equals(Object) Returns whether this result is equal to the other.
(Overrides ValueTypeEquals(Object))
Equals(ResT) Returns true if both values are IsOk and their unwrapped values are equal; false otherwise.
ErrorMessage Returns Some(error-message) if IsErr; None<string>() if IsOk.
C#
var user = Err<User>("failed to get user");
Assert(user.ErrorMessage() == Some("failed to get user"));
FlatMap(FuncT, Res) Returns the error when IsErr; map(Unwrap()) when IsOk flattenning the result. Shorthand combining Map and Flatten calls.
C#
static Res<Team> TryGetTeam() { .. } // tries to grab a team; might fail, hence, returns Res.
static Res TryPutTeam(Team team) { .. } // tries to put the team; might fail, hence, returns Res.

Res result = TryGetTeam().FlatMap(TryPutTeam);
// equivalently:
Res result = TryGetTeam().FlatMap(team => TryPutTeam(team));

// this is a shorthand for:
Res result = TryGetTeam()   // Res<Team>
    .Map(TryPutTeam)        // Res<Res>
    .Flatten();             // Res
FlatMapTOut(FuncT, ResTOut) Returns None when IsNone; map(val) when IsOk flattening the result. Shorthand combining Map and Flatten calls.
C#
static Res<User> TryGetUser() {
    // method that tries to get the user, return Ok(user) or Err.
}
static Res< double> TryGetBalance(User user) {
    // method that tries to get usedr's balance; which might fail, returns:
    // Ok(balance) or Err
}
Res<double> balance = TryGetUser().FlatMap(TryGetBalance);
// equivalent to both below:
var balance = TryGetUser().FlatMap(user => TryGetBalance(user));
var balance = TryGetUser()              // Res<User>
    .Map(user => TryGetBalance(user))   // Res<Res>
    .Flatten();                         // Res
FlatMapAsync(FuncT, TaskRes) (async version) Returns the error when IsErr; map(Unwrap()) when IsOk flattenning the result. Shorthand combining Map and Flatten calls.
C#
static Res<Team> TryGetTeam() { .. } // tries to grab a team; might fail, hence, returns Res.
static Res TryPutTeam(Team team) { .. } // tries to put the team; might fail, hence, returns Res.

Res result = TryGetTeam().FlatMap(TryPutTeam);
// equivalently:
Res result = TryGetTeam().FlatMap(team => TryPutTeam(team));

// this is a shorthand for:
Res result = TryGetTeam()   // Res<Team>
    .Map(TryPutTeam)        // Res<Res>
    .Flatten();             // Res
FlatMapAsyncTOut(FuncT, TaskResTOut) (async version) Returns None when IsNone; map(val) when IsOk flattening the result. Shorthand combining Map and Flatten calls.
C#
static Res<User> TryGetUser() {
    // method that tries to get the user, return Ok(user) or Err.
}
static Res< double> TryGetBalance(User user) {
    // method that tries to get usedr's balance; which might fail, returns:
    // Ok(balance) or Err
}
Res<double> balance = TryGetUser().FlatMap(TryGetBalance);
// equivalent to both below:
var balance = TryGetUser().FlatMap(user => TryGetBalance(user));
var balance = TryGetUser()              // Res<User>
    .Map(user => TryGetBalance(user))   // Res<Res>
    .Flatten();                         // Res
FlatMapBack Returns the error when IsErr; map(Unwrap()).Map(() => this) when IsOk flattenning the result. Shorthand combining Map, Flatten and Map calls.

Note that the difference of FlatMapBack(FuncT, Res) from FlatMap(FuncT, Res) is in the return type; returns Res<T> rather than Res.

It appends back the original value to the result if the result was and is Ok after the map call.

C#
static Res<Team> TryGetTeam() { .. } // tries to grab a team; might fail, hence, returns Res.
static Res TryPutTeam(Team team) { .. } // tries to put the team; might fail, hence, returns Res.

Res<Team> result = TryGetTeam().FlatMapBack(TryPutTeam);
// equivalently:
Res<Team> result = TryGetTeam().FlatMapBack(team => TryPutTeam(team));

// this is a shorthand for:
Res<Team> result = TryGetTeam()                               // Res<Team>
    .FlatMap(team => TryPutTeam(team).Map(() => team)); // Res<Team>
FlatMapBackAsync (async version) Returns the error when IsErr; map(Unwrap()).Map(() => this) when IsOk flattenning the result. Shorthand combining Map, Flatten and Map calls.

Note that the difference of FlatMapBack(FuncT, Res) from FlatMap(FuncT, Res) is in the return type; returns Res<T> rather than Res.

It appends back the original value to the result if the result was and is Ok after the map call.

C#
static Res<Team> TryGetTeam() { .. } // tries to grab a team; might fail, hence, returns Res.
static Res TryPutTeam(Team team) { .. } // tries to put the team; might fail, hence, returns Res.

Res<Team> result = TryGetTeam().FlatMapBack(TryPutTeam);
// equivalently:
Res<Team> result = TryGetTeam().FlatMapBack(team => TryPutTeam(team));

// this is a shorthand for:
Res<Team> result = TryGetTeam()                               // Res<Team>
    .FlatMap(team => TryPutTeam(team).Map(() => team)); // Res<Team>
GetHashCode Serves as the default hash function.
(Overrides ValueTypeGetHashCode)
GetType
(Inherited from Object)
IntoOpt Converts the result type into the option type as follows:
  • Ok(value) => Some(value),
  • Err(error) => None, ignoring the error message.
MapTOut Returns the Err back when IsErr; Ok(map(Unwrap())) when IsOk.
C#
// session will be Err if the user is Err; Ok of a session for the user when Ok.
Res<Session> session = TryGetUser.Map(user => NewSession(user.Secrets));
MapAsyncTOut (async version) Returns the Err back when IsErr; Ok(map(Unwrap())) when IsOk.
C#
// session will be Err if the user is Err; Ok of a session for the user when Ok.
Res<Session> session = TryGetUser.Map(user => NewSession(user.Secrets));
MatchTOut Maps into whenOk(Unwrap()) whenever IsOk; and into whenErr(error-message) otherwise.
C#
Res<User> user = TryGetUser(..);
string greeting = user.Match(u => $"Welcome back {u.Name}", err => $"Failed to get user. {err}");
// equivalently:
greeting = user.Match(
    whenOk: u => $"Welcome back {u.Name}",
    whenErr: err => $"Failed to get user. {err}"
);
MatchAsyncTOut (async version) Maps into whenOk(Unwrap()) whenever IsOk; and into whenErr(error-message) otherwise.
C#
Res<User> user = TryGetUser(..);
string greeting = user.Match(u => $"Welcome back {u.Name}", err => $"Failed to get user. {err}");
// equivalently:
greeting = user.Match(
    whenOk: u => $"Welcome back {u.Name}",
    whenErr: err => $"Failed to get user. {err}"
);
MatchDo Executes whenOk(Unwrap()) if IsOk; whenErr(error-message) otherwise.
C#
Res<User> user = LoginUser(..);
user.MatchDo(
    whenOk: u => Log.Info($"Logged in user: {u.Name}"),
    whenErr: err => Log.Error($"Failed login. ${err}")
);
OkIf Returns back the Err if this is Err. Otherwise, returns Ok(value) if condition(value) holds; Err if it does not hold. Especially useful in fluent input validation.
C#
static Res<Account> TryParseAccount(..) { }
static bool IsAccountNumberValid(int number) { }
static bool DoesAccountExist(string code) { }

var account = TryParseAccount(..)
                .OkIf(acc => IsAccountNumberValid(acc.Number))
                .OkIf(acc => DoesAccountExist(acc.Code));
// account will be Ok(account) only if:
// - TryParseAccount returns Ok(account), and further,
// - both IsAccountNumberValid and DoesAccountExist validation checks return true.
Or(FuncResT) (lazy version) Combines two results: this and other as follows:
  • returns this if this is Ok;
  • returns other otherwise.

In other words, this is a flattened alternative to UnwrapOr(T).

C#
var or = Ok(42).Or(Ok(7));
Assert.Equal(Ok(42), or);

or = Ok(42).Or(Err<int>("error-message"));
Assert.Equal(Ok(42), or);

or = Err<int>("error-message").Or(Ok(7));
Assert.Equal(Ok(7), or);

or = Err<int>("error-message").Or(Err<int>("second-error-message"));
Assert.True(or.IsErr);
Assert.Equal(Some("second-error-message"), or.ErrorMessage());
Or(ResT) Combines two results: this and other as follows:
  • returns this if this is Ok;
  • returns other otherwise.

In other words, this is a flattened alternative to UnwrapOr(T).

C#
var or = Ok(42).Or(Ok(7));
Assert.Equal(Ok(42), or);

or = Ok(42).Or(Err<int>("error-message"));
Assert.Equal(Ok(42), or);

or = Err<int>("error-message").Or(Ok(7));
Assert.Equal(Ok(7), or);

or = Err<int>("error-message").Or(Err<int>("second-error-message"));
Assert.True(or.IsErr);
Assert.Equal(Some("second-error-message"), or.ErrorMessage());
Pure Simply returns Ok<T> function: val => Ok(val). Useful for composing functions of Res<T> type.
ThrowIfErr Returns the result back when IsOk; throws a NullReferenceException when IsErr.
C#
static Res<User> QueryUser(..) {
    // might fail; hence, returns a Res<User> rather than just User.
}
var result = QueryUser(..).ThrowIfErr();
// result will be:
// - Ok(user) if QueryUser succeeds and returns Ok of the user;
// - the application will throw otherwise.
ThrowIfErrE(FuncString, E) Returns the result back when IsOk; throws an exception of E when IsErr.
C#
static Res MakeApiCall() {
    // method that makes an api call.
    // might fail; hence, returns a Res rather than void.
}
var result = MakeApiCall().ThrowIfErr<HttpRequestException>(err => new(err));
// result will be:
// - Ok() if MakeApiCall succeeds and returns Ok;
// - the application will throw HttpRequestException created by the provided delegate otherwise.
ToErrOfTOut Converts the result to Err<TOut> regardless of state of this result:
  • The error message will be carried on when this is of Err variant,
  • A generic error message will be created otherwise.
ToString String representation.
(Overrides ValueTypeToString)
Try When IsOk executes action(val) in a try-catch block: returns Ok if the process succeeds; Err if it throws. Does not do anything and returns the Err when this IsErr.
C#
static Res<User> TryGetUser() { .. }
static void PutUserToDb(User user) {
    // method that writes the user to a database table
    // might fail and throw!
}

Res<User> user = TryGetUser().Try(PutUserToDb);
// equivalently:
Res<User> user = TryGetUser().Try(() => PutUserToDb());

// user will be:
// - Err(called on Err) if () returns Err.
// - Err(relevant error message) if () returns Ok(user) but database action throws an exception.
// - Ok(user) if () returns Ok(user), further the action is operated successfully;

// it provides a shorthand for the following verbose/unpleasant version:
Res<User> user = TryGetUser();
if (user.IsOk)
{
    try
    {
        PutUserToDb(user.Unwrap());
    }
    catch (Exception e)
    {
        user = Err<User>("db-operation failed, check the exception message: " + e.Message);
    }
}
TryAsync (async version) When IsOk executes action(val) in a try-catch block: returns Ok if the process succeeds; Err if it throws. Does not do anything and returns the Err when this IsErr.
C#
static Res<User> TryGetUser() { .. }
static void PutUserToDb(User user) {
    // method that writes the user to a database table
    // might fail and throw!
}

Res<User> user = TryGetUser().Try(PutUserToDb);
// equivalently:
Res<User> user = TryGetUser().Try(() => PutUserToDb());

// user will be:
// - Err(called on Err) if () returns Err.
// - Err(relevant error message) if () returns Ok(user) but database action throws an exception.
// - Ok(user) if () returns Ok(user), further the action is operated successfully;

// it provides a shorthand for the following verbose/unpleasant version:
Res<User> user = TryGetUser();
if (user.IsOk)
{
    try
    {
        PutUserToDb(user.Unwrap());
    }
    catch (Exception e)
    {
        user = Err<User>("db-operation failed, check the exception message: " + e.Message);
    }
}
TryFlatMapTOut Returns the error when IsErr. Otherwise, tries to return map(val) in a try-catch block and returns the Err if it throws.
C#
static Res<User> TryGetUser() { .. }
static Res<long> PutUserToDbGetId(User user) {
    // method that writes the user to a database table and returns back the auto-generated id/primary-key
    // might throw in cases of connection errors!
}

Res<long> id = TryGetUser().TryFlatMap(PutUserToDbGetId);
// equivalently:
Res<long> id = TryGetUser().TryFlatMap(user => PutUserToDbGetId(user));
// Res<long> id will be:
// - Err(called on Err) when TryGetUser returns Err,
// - Err(relevant error message) when TryGetUser returns Ok(user) but PutUserToDbGetId returns an Err,
// - Err(relevant error message) when TryGetUser returns Ok(user) but the database transaction throws an exception,
// - Ok(id) when TryGetUser returns Ok(user), the database transaction succeeds and returns the auto-generated id.
TryFlatMapAsyncTOut (async version) Returns the error when IsErr. Otherwise, tries to return map(val) in a try-catch block and returns the Err if it throws.
C#
static Res<User> TryGetUser() { .. }
static Res<long> PutUserToDbGetId(User user) {
    // method that writes the user to a database table and returns back the auto-generated id/primary-key
    // might throw in cases of connection errors!
}

Res<long> id = TryGetUser().TryFlatMap(PutUserToDbGetId);
// equivalently:
Res<long> id = TryGetUser().TryFlatMap(user => PutUserToDbGetId(user));
// Res<long> id will be:
// - Err(called on Err) when TryGetUser returns Err,
// - Err(relevant error message) when TryGetUser returns Ok(user) but PutUserToDbGetId returns an Err,
// - Err(relevant error message) when TryGetUser returns Ok(user) but the database transaction throws an exception,
// - Ok(id) when TryGetUser returns Ok(user), the database transaction succeeds and returns the auto-generated id.
TryMapTOut Returns the error when IsErr. Otherwise, tries to map into Ok(map(val)) in a try-catch block and returns the Err if it throws.
C#
static Res<User> TryGetUser() { .. }
static long PutUserToDbGetId(User user) {
    // method that writes the user to a database table and returns back the auto-generated id/primary-key
    // might fail and throw!
}

Res<long> id = TryGetUser().TryMap(PutUserToDbGetId);
// equivalently:
Res<long> id = TryGetUser().TryMap(user => PutUserToDbGetId(user));
// Res<long> id will be:
// - Err(called on Err) when TryGetUser returns Err,
// - Err(relevant error message) when TryGetUser returns Ok(user) but the database transaction throws an exception,
// - Ok(id) when TryGetUser returns Ok(user), the database transaction succeeds and returns the auto-generated id.

// it provides a shorthand for the following verbose/unpleasant version:
Opt<User> user = TryGetUser();
Res<long> id;
if (user.IsNone)
    id = Err<long>("no user");
else
{
    try
    {
        id = Ok(PutUserToDb(user.Unwrap()));
    }
    catch (Exception e)
    {
        id = Err<long>("db-operation failed, check the exception message: " + e.Message);
    }
}
TryMapAsyncTOut (async version) Returns the error when IsErr. Otherwise, tries to map into Ok(map(val)) in a try-catch block and returns the Err if it throws.
C#
static Res<User> TryGetUser() { .. }
static long PutUserToDbGetId(User user) {
    // method that writes the user to a database table and returns back the auto-generated id/primary-key
    // might fail and throw!
}

Res<long> id = TryGetUser().TryMap(PutUserToDbGetId);
// equivalently:
Res<long> id = TryGetUser().TryMap(user => PutUserToDbGetId(user));
// Res<long> id will be:
// - Err(called on Err) when TryGetUser returns Err,
// - Err(relevant error message) when TryGetUser returns Ok(user) but the database transaction throws an exception,
// - Ok(id) when TryGetUser returns Ok(user), the database transaction succeeds and returns the auto-generated id.

// it provides a shorthand for the following verbose/unpleasant version:
Opt<User> user = TryGetUser();
Res<long> id;
if (user.IsNone)
    id = Err<long>("no user");
else
{
    try
    {
        id = Ok(PutUserToDb(user.Unwrap()));
    }
    catch (Exception e)
    {
        id = Err<long>("db-operation failed, check the exception message: " + e.Message);
    }
}
Unwrap Returns the underlying value when IsOk; or throws when IsErr. Must be called shyly, as it is not necessary to unwrap until the final result is achieved due to Map, FlatMap and TryMap methods.
C#
Res<int> resultAge = "42".ParseIntOrErr();
if (resultAge.IsSome) {
    int age = resultAge.Unwrap(); // use the uwrapped age
} else { // handle the Err case
}
UnwrapOr(FuncT) Returns the underlying value when IsOk; or returns lazyFallbackValue() when IsErr. This is a safe way to unwrap the result, by explicitly handling the Err variant. Use the eager UnwrapOr(T) variant if the fallback value is cheap or readily available.
C#
static string ParseUserTablename(..) { /*parses the table name from command line input; might throw!*/ }
static string QueryUserTablename(..) { /*makes an expensive db-call to find out the table name*/ }

string userTable = Ok()                                         // Res, certainly Ok
                    .TryMap(() => ParseUserTablename(..))       // Res<string>: might be Err if parser throws
                    .UnwrapOr(() => QueryUserTablename(..));    // directly returns ParseUserTablename's result if it is Ok;
                                                                // calls QueryUserTablename otherwise and returns its result.
UnwrapOr(T) Returns the underlying value when IsOk; or returns the fallbackValue when IsErr. This is a safe way to unwrap the result, by explicitly handling the Err variant. Use the lazy UnwrapOr(FuncT) variant if the computation of the fallback value is expensive.
C#
Assert(Ok(42).UnwrapOr(7) == 42);
Assert(Err<int>("error-message").UnwrapOr(7) == 7);
UnwrapOrAsync (async version) Returns the underlying value when IsOk; or returns lazyFallbackValue() when IsErr. This is a safe way to unwrap the result, by explicitly handling the Err variant. Use the eager UnwrapOr(T) variant if the fallback value is cheap or readily available.
C#
static string ParseUserTablename(..) { /*parses the table name from command line input; might throw!*/ }
static string QueryUserTablename(..) { /*makes an expensive db-call to find out the table name*/ }

string userTable = Ok()                                         // Res, certainly Ok
                    .TryMap(() => ParseUserTablename(..))       // Res<string>: might be Err if parser throws
                    .UnwrapOr(() => QueryUserTablename(..));    // directly returns ParseUserTablename's result if it is Ok;
                                                                // calls QueryUserTablename otherwise and returns its result.
WithoutVal Converts into Res dropping the value if it IsOk.

Operators

BitwiseOr(ResT, FuncT, ResT)

Limited ahd experimental for now; waiting for generics in operator overloading to be actually useful.

Returns None when IsNone; map(val) when IsOk flattening the result. Shorthand combining Map and Flatten calls.
C#
static Res<User> TryGetUser() {
    // method that tries to get the user, return Ok(user) or Err.
}
static Res< double> TryGetBalance(User user) {
    // method that tries to get usedr's balance; which might fail, returns:
    // Ok(balance) or Err
}
Res<double> balance = TryGetUser().FlatMap(TryGetBalance);
// equivalent to both below:
var balance = TryGetUser().FlatMap(user => TryGetBalance(user));
var balance = TryGetUser()              // Res<User>
    .Map(user => TryGetBalance(user))   // Res<Res>
    .Flatten();                         // Res
BitwiseOr(ResT, FuncT, Res)

Limited ahd experimental for now; waiting for generics in operator overloading to be actually useful.

Returns the error when IsErr; map(Unwrap()) when IsOk flattenning the result. Shorthand combining Map and Flatten calls.
C#
static Res<Team> TryGetTeam() { .. } // tries to grab a team; might fail, hence, returns Res.
static Res TryPutTeam(Team team) { .. } // tries to put the team; might fail, hence, returns Res.

Res result = TryGetTeam().FlatMap(TryPutTeam);
// equivalently:
Res result = TryGetTeam().FlatMap(team => TryPutTeam(team));

// this is a shorthand for:
Res result = TryGetTeam()   // Res<Team>
    .Map(TryPutTeam)        // Res<Res>
    .Flatten();             // Res
Division(ResT, FuncT, T)

Limited ahd experimental for now; waiting for generics in operator overloading to be actually useful.

Returns the Err back when IsErr; Ok(map(Unwrap())) when IsOk.
C#
// session will be Err if the user is Err; Ok of a session for the user when Ok.
Res<Session> session = TryGetUser.Map(user => NewSession(user.Secrets));
Equality(ResT, ResT) Returns true if both results are IsOk and their unwrapped values are equal; false otherwise.
C#
AssertEqual(Err<int>() == Err<int>(), false);
AssertEqual(Err<int>() == Ok(42), false);
AssertEqual(Ok(42) == Err<int>(), false);
AssertEqual(Ok(42) == Ok(7), false);
AssertEqual(Ok(42) == Ok(42), true);
Inequality(ResT, ResT) Returns true if either value is IsErr or their unwrapped values are not equal; false otherwise.
C#
AssertEqual(Err<int>() != Err<int>(), true);
AssertEqual(Err<int>() != Ok(42), true);
AssertEqual(Ok(42) != Err<int>(), true);
AssertEqual(Ok(42) != Ok(7), true);
AssertEqual(Ok(42) != Ok(42), false);

See Also