diff --git a/base/base_tests/CMakeLists.txt b/base/base_tests/CMakeLists.txt index 1b69fab526..628b4bea9c 100644 --- a/base/base_tests/CMakeLists.txt +++ b/base/base_tests/CMakeLists.txt @@ -48,6 +48,7 @@ set( timegm_test.cpp timer_test.cpp uni_string_dfa_test.cpp + url_helpers_tests.cpp visitor_tests.cpp ) diff --git a/base/base_tests/url_helpers_tests.cpp b/base/base_tests/url_helpers_tests.cpp new file mode 100644 index 0000000000..dead198d4e --- /dev/null +++ b/base/base_tests/url_helpers_tests.cpp @@ -0,0 +1,14 @@ +#include "testing/testing.hpp" + +#include "base/url_helpers.hpp" + +UNIT_TEST(Url_Join) +{ + TEST_EQUAL("", base::url::Join("", ""), ()); + TEST_EQUAL("omim/strings", base::url::Join("omim", "strings"), ()); + TEST_EQUAL("omim/strings", base::url::Join("omim/", "strings"), ()); + TEST_EQUAL("../../omim/strings", base::url::Join("..", "..", "omim", "strings"), ()); + TEST_EQUAL("../../omim/strings", base::url::Join("../", "..", "omim/", "strings"), ()); + TEST_EQUAL("omim/strings", base::url::Join("omim/", "/strings"), ()); + TEST_EQUAL("../../omim/strings", base::url::Join("../", "/../", "/omim/", "/strings"), ()); +} diff --git a/base/url_helpers.cpp b/base/url_helpers.cpp index a53cc82445..e8b6d53aa5 100644 --- a/base/url_helpers.cpp +++ b/base/url_helpers.cpp @@ -31,5 +31,21 @@ string Make(string const & baseUrl, Params const & params) return os.str(); } + +std::string Join(std::string const & lhs, std::string const & rhs) +{ + if (lhs.empty()) + return rhs; + if (rhs.empty()) + return lhs; + + if (lhs.back() == '/' && rhs.front() == '/') + return lhs + rhs.substr(1); + + if (lhs.back() != '/' && rhs.front() != '/') + return lhs + '/' + rhs; + + return lhs + rhs; +} } // namespace url } // namespace base diff --git a/base/url_helpers.hpp b/base/url_helpers.hpp index ce27431a09..466cf4e913 100644 --- a/base/url_helpers.hpp +++ b/base/url_helpers.hpp @@ -20,5 +20,19 @@ using Params = std::vector; // Make URL by using base url and vector of params. std::string Make(std::string const & baseUrl, Params const & params); + +// Joins URL, appends/removes slashes if needed. +std::string Join(std::string const & lhs, std::string const & rhs); + +template +std::string Join(std::string const & lhs, std::string const & rhs, Args &&... args) +{ + if (lhs.empty()) + return Join(rhs, std::forward(args)...); + if (rhs.empty()) + return Join(lhs, std::forward(args)...); + + return Join(Join(lhs, rhs), std::forward(args)...); +} } // namespace url } // namespace base