feat: add into method to Option and Result + macro try_unwrap

This commit is contained in:
DL 2024-02-28 17:32:16 +01:00
parent 7a9e022528
commit b8ac4c450c
2 changed files with 69 additions and 0 deletions

View File

@ -10,6 +10,7 @@
#define None(T) (ro::Option<T>()) #define None(T) (ro::Option<T>())
#define Some(v) (ro::Option(v)) #define Some(v) (ro::Option(v))
#define ERR(fmt, ...) Error(ro::sfmt("%s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__)) #define ERR(fmt, ...) Error(ro::sfmt("%s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__))
#define try_unwrap(l,...) try{l=(__VA_ARGS__).unwrap();}catch(ro::Error e){return e;}
// #define Err(e) (ro::Result(e)) // #define Err(e) (ro::Result(e))
// #define Ok(v) (ro::Result(v)) // #define Ok(v) (ro::Result(v))
@ -181,6 +182,16 @@ namespace ro
return fn(); return fn();
} }
inline bool into(T &output) const
{
if(is_some())
{
output = m_some;
return true;
}
return false;
}
template <typename U> template <typename U>
inline Option<U> map(const std::function<U(const T &)> &fn) inline Option<U> map(const std::function<U(const T &)> &fn)
{ {
@ -404,6 +415,16 @@ namespace ro
return alt; return alt;
} }
inline bool into(T &output) const
{
if(is_ok())
{
output = m_result;
return true;
}
return false;
}
inline T unwrap_or_else(const std::function<T(const E &)> &fn) inline T unwrap_or_else(const std::function<T(const E &)> &fn)
{ {
if (is_ok()) if (is_ok())

View File

@ -19,6 +19,10 @@ static Stat g_stat = {0,0};
throw Error(ro::sfmt("ASSERT ERROR %s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__)); \ throw Error(ro::sfmt("ASSERT ERROR %s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__)); \
} }
class TestError: public Error {
public:
TestError(const char *s) : Error(s){};
};
void test(const char* desc, const std::function<void()>& lambda) void test(const char* desc, const std::function<void()>& lambda)
{ {
@ -36,6 +40,13 @@ void test(const char* desc, const std::function<void()>& lambda)
g_stat.total++; g_stat.total++;
} }
Result<int, Error> test_macro(const Result<int, Error> & target)
{
int a;
try_unwrap(a,target);
return a;
}
int main(int argc, char const *argv[]) int main(int argc, char const *argv[])
{ {
test("Test Option", [](){ test("Test Option", [](){
@ -232,6 +243,20 @@ int main(int argc, char const *argv[])
}); });
test("Option Into", [](){
Option<int> x = 2;
int y = 0;
bool v = x.into(y);
assert(v, "Return value shall be true");
assert(y == 2, "Unexpected value");
x = None(int);
v = x.into(y);
y = 0;
assert(v == false, "Return value shall not be true");
assert(y == 0, "Unexpected value");
});
test("Test Result", []{ test("Test Result", []{
Result<string, Error> ret = ERR("Error"); Result<string, Error> ret = ERR("Error");
assert(ret.is_err(), "Object should containe error object"); assert(ret.is_err(), "Object should containe error object");
@ -263,6 +288,7 @@ int main(int argc, char const *argv[])
catch(Error e) catch(Error e)
{ {
assert(true, "%s", e.what()); assert(true, "%s", e.what());
cout << e.what() << endl;
} }
}); });
@ -396,5 +422,27 @@ int main(int argc, char const *argv[])
}); });
test("Result Into", [](){
Result<int, Error> x = 2;
int y = 0;
bool v = x.into(y);
assert(v, "Return value shall be true");
assert(y == 2, "Unexpected value");
x = ERR("Error");
v = x.into(y);
y = 0;
assert(v == false, "Return value shall not be true");
assert(y == 0, "Unexpected value");
});
test("try_unwrap", [](){
Result<int, Error> x = test_macro(Result<int, Error>(10));
assert(x == 10, "Unexpected value");
x = test_macro(Result<int, Error>(Error("Hello")));
assert(x.is_err(), "Unexpected value");
});
cout << "REPORT: " << g_stat.passed << " tests passed / " << g_stat.total << " tests." << endl; cout << "REPORT: " << g_stat.passed << " tests passed / " << g_stat.total << " tests." << endl;
} }