From b8ac4c450c5994971ee415c9a1e9494785786e2e Mon Sep 17 00:00:00 2001 From: Dany LE Date: Wed, 28 Feb 2024 17:32:16 +0100 Subject: [PATCH] feat: add into method to Option and Result + macro try_unwrap --- src/ro.h | 21 +++++++++++++++++++++ test/test.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/src/ro.h b/src/ro.h index 587299a..1882f4c 100644 --- a/src/ro.h +++ b/src/ro.h @@ -10,6 +10,7 @@ #define None(T) (ro::Option()) #define Some(v) (ro::Option(v)) #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 Ok(v) (ro::Result(v)) @@ -181,6 +182,16 @@ namespace ro return fn(); } + inline bool into(T &output) const + { + if(is_some()) + { + output = m_some; + return true; + } + return false; + } + template inline Option map(const std::function &fn) { @@ -404,6 +415,16 @@ namespace ro 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 &fn) { if (is_ok()) diff --git a/test/test.cpp b/test/test.cpp index 37394a1..5646f69 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -19,6 +19,10 @@ static Stat g_stat = {0,0}; 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& lambda) { @@ -36,6 +40,13 @@ void test(const char* desc, const std::function& lambda) g_stat.total++; } +Result test_macro(const Result & target) +{ + int a; + try_unwrap(a,target); + return a; +} + int main(int argc, char const *argv[]) { test("Test Option", [](){ @@ -231,6 +242,20 @@ int main(int argc, char const *argv[]) assert(x.zip(z).is_none(), "Unexpected value"); }); + + test("Option Into", [](){ + Option 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", []{ Result ret = ERR("Error"); @@ -263,6 +288,7 @@ int main(int argc, char const *argv[]) catch(Error e) { assert(true, "%s", e.what()); + cout << e.what() << endl; } }); @@ -396,5 +422,27 @@ int main(int argc, char const *argv[]) }); + test("Result Into", [](){ + Result 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 x = test_macro(Result(10)); + assert(x == 10, "Unexpected value"); + + x = test_macro(Result(Error("Hello"))); + assert(x.is_err(), "Unexpected value"); + }); + cout << "REPORT: " << g_stat.passed << " tests passed / " << g_stat.total << " tests." << endl; }