From 992fa938951558f4515145c9b82af0123c979a29 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Sun, 21 Aug 2016 01:04:32 +0200
Subject: Add get_first_non_empty and use it into Database to simplify a little
 bit

---
 CMakeLists.txt                    |  2 +-
 src/database/database.cpp         | 11 ++++++-----
 src/utils/get_first_non_empty.cpp | 11 +++++++++++
 src/utils/get_first_non_empty.hpp | 20 ++++++++++++++++++++
 tests/utils.cpp                   | 11 +++++++++++
 5 files changed, 49 insertions(+), 6 deletions(-)
 create mode 100644 src/utils/get_first_non_empty.cpp
 create mode 100644 src/utils/get_first_non_empty.hpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index d5b1f52..ea9ffc3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -96,7 +96,7 @@ if(LITESQL_FOUND)
 
   add_library(database STATIC src/database/database.cpp
     ${LITESQL_GENERATED_SOURCES})
-  target_link_libraries(database ${LITESQL_LIBRARIES})
+  target_link_libraries(database ${LITESQL_LIBRARIES} src_utils)
   if(BOTAN_FOUND)
     target_link_libraries(database ${BOTAN_LIBRARIES})
   endif()
diff --git a/src/database/database.cpp b/src/database/database.cpp
index 5513946..3891f41 100644
--- a/src/database/database.cpp
+++ b/src/database/database.cpp
@@ -4,8 +4,8 @@
 #include <database/database.hpp>
 #include <logger/logger.hpp>
 #include <irc/iid.hpp>
-#include <string>
 #include <uuid.h>
+#include <utils/get_first_non_empty.hpp>
 
 using namespace std::string_literals;
 
@@ -73,10 +73,11 @@ db::IrcChannelOptions Database::get_irc_channel_options_with_server_default(cons
 {
   auto coptions = Database::get_irc_channel_options(owner, server, channel);
   auto soptions = Database::get_irc_server_options(owner, server);
-  if (coptions.encodingIn.value().empty())
-    coptions.encodingIn = soptions.encodingIn;
-  if (coptions.encodingOut.value().empty())
-    coptions.encodingOut = soptions.encodingOut;
+
+  coptions.encodingIn = get_first_non_empty(coptions.encodingIn.value(),
+                                            soptions.encodingIn.value());
+  coptions.encodingOut = get_first_non_empty(coptions.encodingOut.value(),
+                                             soptions.encodingOut.value());
 
   return coptions;
 }
diff --git a/src/utils/get_first_non_empty.cpp b/src/utils/get_first_non_empty.cpp
new file mode 100644
index 0000000..5b3bedb
--- /dev/null
+++ b/src/utils/get_first_non_empty.cpp
@@ -0,0 +1,11 @@
+#include <utils/get_first_non_empty.hpp>
+
+bool is_empty(const std::string& val)
+{
+  return val.empty();
+}
+
+bool is_empty(const int& val)
+{
+  return val == 0;
+}
diff --git a/src/utils/get_first_non_empty.hpp b/src/utils/get_first_non_empty.hpp
new file mode 100644
index 0000000..a38f5fb
--- /dev/null
+++ b/src/utils/get_first_non_empty.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <string>
+
+bool is_empty(const std::string& val);
+bool is_empty(const int& val);
+
+template <typename T>
+T get_first_non_empty(T&& last)
+{
+  return last;
+}
+
+template <typename T, typename... Args>
+T get_first_non_empty(T&& first, Args&&... args)
+{
+  if (!is_empty(first))
+    return first;
+  return get_first_non_empty(std::forward<Args>(args)...);
+}
diff --git a/tests/utils.cpp b/tests/utils.cpp
index 01d070e..e7ba415 100644
--- a/tests/utils.cpp
+++ b/tests/utils.cpp
@@ -6,6 +6,9 @@
 #include <utils/split.hpp>
 #include <utils/xdg.hpp>
 #include <utils/empty_if_fixed_server.hpp>
+#include <utils/get_first_non_empty.hpp>
+
+using namespace std::string_literals;
 
 TEST_CASE("String split")
 {
@@ -100,3 +103,11 @@ TEST_CASE("string cut")
   CHECK(res[0] == "rhello, ");
   CHECK(res[1] == "♥");
 }
+
+TEST_CASE("first non-empty string")
+{
+  CHECK(get_first_non_empty(""s, ""s, "hello"s, "world"s) == "hello"s);
+  CHECK(get_first_non_empty(""s, ""s, ""s, ""s) == ""s);
+  CHECK(get_first_non_empty("first"s) == "first"s);
+  CHECK(get_first_non_empty(0, 1, 2, 3) == 1);
+}
-- 
cgit v1.2.3