Add Result<Value, ErrCode> type for error handling
authorSangwan Kwon <sangwan.kwon@samsung.com>
Fri, 8 Nov 2019 05:36:11 +0000 (14:36 +0900)
committerSangwan Kwon <sangwan.kwon@samsung.com>
Fri, 8 Nov 2019 05:41:41 +0000 (14:41 +0900)
Result<Valud, ErrCode> type contains either value or error_code.
This is inspired by rust's syntax(std::result::Result).
(ref: https://doc.rust-lang.org/std/result/enum.Result.html)

Signed-off-by: Sangwan Kwon <sangwan.kwon@samsung.com>
src/vist/exception.hpp
src/vist/logger.hpp
src/vist/result.hpp [new file with mode: 0644]
src/vist/tests/result.cpp [new file with mode: 0644]

index 5c4bfad..5a8cec2 100644 (file)
@@ -14,7 +14,7 @@
  *  limitations under the License
  */
 /*
- * @brief Enum based exception handling
+ * @brief Enum based exception handling.
  * @usage
  *  boilerplate : THROW(${ERROR_CODE: ENUM_TYPE}) << ${MESSAGE_STREAM}
  *
index 801a9c1..28ffe8b 100644 (file)
@@ -14,7 +14,7 @@
  *  limitations under the License
  */
 /*
- * @brief Logging macro for dlog
+ * @brief Logging macro for dlog.
  * @usage
  *  boilerplate : ${LEVEL}(${TAG}) << ${MESSAGE_STREAM}
  *
diff --git a/src/vist/result.hpp b/src/vist/result.hpp
new file mode 100644 (file)
index 0000000..b00f800
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *  Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @brief Result<Valud, ErrCode> type contains either value or error_code.
+ *        This is inspired by rust's syntax(std::result::Result).
+ *        (ref: https://doc.rust-lang.org/std/result/enum.Result.html)
+ * @usage
+ *  enum class FileErr {
+ *    InvalidArgument = 1,
+ *    NotFound
+ *  };
+ *
+ *  Result<std::string, FileErr> read(const std::string& path)
+ *  {
+ *    if (path.empty())
+ *      return FileErr::InvalidArgument;
+ *
+ *    // Read process
+ *    return "File contents";
+ *  }
+ *
+ *  auto result = read("foo.txt");
+ *  if (result.ok())
+ *    std::string content = result.get();
+ *  else
+ *    FileErr ec = result.getErrCode();
+ */
+
+#pragma once
+
+#include <type_traits>
+#include <utility>
+
+namespace vist {
+
+template <typename Value, typename ErrCode>
+class Result final {
+public:
+       static_assert(std::is_enum<ErrCode>::value, "Error code must be enum type.");
+       static_assert(!std::is_reference<Value>::value,
+                                 "Value type must not be reference.");
+
+       Result(Value value) : value(std::move(value)), isError(false) {}
+       Result(ErrCode ec) : ec(std::move(ec)), isError(true) {}
+       Result() = delete;
+
+       inline bool ok() { return !isError; }
+       inline bool err() { return isError; }
+
+       /// TBD: Consider to return rvalue.
+       inline Value& get() { return value; }
+       inline ErrCode getErrCode() { return ec; }
+
+private:
+       Value value;
+       ErrCode ec;
+       bool isError = false;
+};
+
+} // namespace vist
diff --git a/src/vist/tests/result.cpp b/src/vist/tests/result.cpp
new file mode 100644 (file)
index 0000000..c1a6a33
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ *  Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#include <gtest/gtest.h>
+
+#include <vist/result.hpp>
+
+#include <string>
+#include <vector>
+
+class ResultTests : public testing::Test {};
+
+using namespace vist;
+
+enum class FileErr {
+       InvalidArgument,
+       NotFound
+};
+
+Result<std::string, FileErr> readSuccess()
+{
+       return std::string("File contents");
+}
+
+Result<std::string, FileErr> readFail()
+{
+       return FileErr::NotFound;
+}
+
+Result<std::vector<int>, FileErr> readVector()
+{
+       std::vector<int> v{1, 2, 3};
+       return v;
+}
+
+TEST_F(ResultTests, success)
+{
+       EXPECT_TRUE(readSuccess().ok());
+       EXPECT_TRUE(!readSuccess().err());
+       EXPECT_NE(std::string::npos, readSuccess().get().find("File"));
+}
+
+TEST_F(ResultTests, fail)
+{
+       EXPECT_TRUE(readFail().err());
+       EXPECT_TRUE(!readFail().ok());
+       EXPECT_EQ(FileErr::NotFound, readFail().getErrCode());
+}
+
+TEST_F(ResultTests, vector)
+{
+       EXPECT_TRUE(readVector().ok());
+       EXPECT_TRUE(!readVector().err());
+       EXPECT_EQ(3, readVector().get().size());
+}