Scott E. Graves a0432be819
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
updated build system
2024-08-04 12:42:23 -05:00

408 lines
13 KiB
C++

/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_UTILS_PATH_HPP_
#define REPERTORY_INCLUDE_UTILS_PATH_HPP_
#include "utils/config.hpp"
#include "utils/string.hpp"
namespace repertory::utils::path {
inline constexpr const std::string_view backslash{"\\"};
inline constexpr const std::wstring_view backslash_w{L"\\"};
inline constexpr const std::string_view dot{"."};
inline constexpr const std::wstring_view dot_w{L"."};
inline constexpr const std::string_view dot_slash{"./"};
inline constexpr const std::wstring_view dot_slash_w{L"./"};
inline constexpr const std::string_view slash{"/"};
inline constexpr const std::wstring_view slash_w{L"/"};
#if defined(_WIN32)
inline constexpr const std::string_view directory_seperator{backslash};
inline constexpr const std::wstring_view directory_seperator_w{backslash_w};
inline constexpr const std::string_view not_directory_seperator{slash};
inline constexpr const std::wstring_view not_directory_seperator_w{slash_w};
#else // !defined(_WIN32)
inline constexpr const std::string_view directory_seperator{slash};
inline constexpr const std::wstring_view directory_seperator_w{slash_w};
inline constexpr const std::string_view not_directory_seperator{backslash};
inline constexpr const std::wstring_view not_directory_seperator_w{backslash_w};
#endif // defined(_WIN32)
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_backslash() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_backslash<char>() -> std::basic_string_view<char> {
return backslash;
}
template <>
[[nodiscard]] inline constexpr auto
get_backslash<wchar_t>() -> std::basic_string_view<wchar_t> {
return backslash_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto get_dot() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_dot<char>() -> std::basic_string_view<char> {
return dot;
}
template <>
[[nodiscard]] inline constexpr auto
get_dot<wchar_t>() -> std::basic_string_view<wchar_t> {
return dot_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_dot_slash() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_dot_slash<char>() -> std::basic_string_view<char> {
return dot_slash;
}
template <>
[[nodiscard]] inline constexpr auto
get_dot_slash<wchar_t>() -> std::basic_string_view<wchar_t> {
return dot_slash_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_slash() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_slash<char>() -> std::basic_string_view<char> {
return slash;
}
template <>
[[nodiscard]] inline constexpr auto
get_slash<wchar_t>() -> std::basic_string_view<wchar_t> {
return slash_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_directory_seperator() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_directory_seperator<char>() -> std::basic_string_view<char> {
return directory_seperator;
}
template <>
[[nodiscard]] inline constexpr auto
get_directory_seperator<wchar_t>() -> std::basic_string_view<wchar_t> {
return directory_seperator_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_not_directory_seperator() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_not_directory_seperator<char>() -> std::basic_string_view<char> {
return not_directory_seperator;
}
template <>
[[nodiscard]] inline constexpr auto
get_not_directory_seperator<wchar_t>() -> std::basic_string_view<wchar_t> {
return not_directory_seperator_w;
}
[[nodiscard]] auto absolute(std::string_view path) -> std::string;
[[nodiscard]] auto absolute(std::wstring_view path) -> std::wstring;
[[nodiscard]] inline auto
combine(std::string path,
const std::vector<std::string_view> &paths) -> std::string;
[[nodiscard]] inline auto
combine(std::wstring path,
const std::vector<std::wstring_view> &paths) -> std::wstring;
[[nodiscard]] auto inline create_api_path(std::string_view path) -> std::string;
[[nodiscard]] auto inline create_api_path(std::wstring_view path)
-> std::wstring;
[[nodiscard]] inline auto
directory_exists_in_path(std::string_view path,
std::string_view sub_directory) -> bool;
[[nodiscard]] inline auto
directory_exists_in_path(std::wstring_view path,
std::wstring_view sub_directory) -> bool;
[[nodiscard]] inline auto
file_exists_in_path(std::string_view path, std::string_view file_name) -> bool;
[[nodiscard]] inline auto
file_exists_in_path(std::wstring_view path,
std::wstring_view file_name) -> bool;
[[nodiscard]] inline auto finalize(std::string_view path) -> std::string;
[[nodiscard]] inline auto finalize(std::wstring_view path) -> std::wstring;
[[nodiscard]] auto
find_program_in_path(const std::string &name_without_extension) -> std::string;
[[nodiscard]] auto
find_program_in_path(std::wstring_view name_without_extension) -> std::wstring;
template <typename string_t>
inline auto
format_path(string_t &path,
std::basic_string_view<typename string_t::value_type> sep,
std::basic_string_view<typename string_t::value_type> not_sep)
-> string_t &;
[[nodiscard]] inline auto
get_parent_api_path(std::string_view path) -> std::string;
[[nodiscard]] inline auto
get_parent_api_path(std::wstring_view path) -> std::wstring;
[[nodiscard]] auto get_parent_directory(std::string_view path) -> std::string;
[[nodiscard]] auto get_parent_directory(std::wstring_view path) -> std::wstring;
[[nodiscard]] auto is_trash_directory(std::string_view path) -> bool;
[[nodiscard]] auto is_trash_directory(std::wstring_view path) -> bool;
[[nodiscard]] auto make_file_uri(std::string_view path) -> std::string;
[[nodiscard]] auto make_file_uri(std::wstring_view path) -> std::wstring;
[[nodiscard]] auto remove_file_name(std::string_view path) -> std::string;
[[nodiscard]] auto remove_file_name(std::wstring_view path) -> std::wstring;
[[nodiscard]] auto strip_to_file_name(std::string path) -> std::string;
[[nodiscard]] auto strip_to_file_name(std::wstring path) -> std::wstring;
[[nodiscard]] auto unmake_file_uri(std::string_view uri) -> std::string;
[[nodiscard]] auto unmake_file_uri(std::wstring_view uri) -> std::wstring;
template <typename string_t>
[[nodiscard]] inline auto combine_t(
string_t path,
const std::vector<std::basic_string_view<typename string_t::value_type>>
&paths) -> string_t {
path = std::accumulate(
paths.begin(), paths.end(), path, [](auto next_path, auto &&path_part) {
if (next_path.empty()) {
return string_t{path_part};
}
return next_path +
string_t{
get_directory_seperator<typename string_t::value_type>()} +
string_t{path_part};
});
return absolute(path);
}
inline auto combine(std::string path,
const std::vector<std::string_view> &paths) -> std::string {
return combine_t<std::string>(path, paths);
}
inline auto
combine(std::wstring path,
const std::vector<std::wstring_view> &paths) -> std::wstring {
return combine_t<std::wstring>(path, paths);
}
template <typename string_t>
[[nodiscard]] inline auto create_api_path_t(
std::basic_string_view<typename string_t::value_type> path) -> string_t {
auto backslash_t = get_backslash<typename string_t::value_type>();
auto dot_t = get_dot<typename string_t::value_type>();
auto dot_slash_t = get_dot_slash<typename string_t::value_type>();
auto slash_t = get_slash<typename string_t::value_type>();
if (path.empty() || path == backslash_t || path == dot_t ||
path == dot_slash_t || path == slash_t) {
return string_t{slash_t};
}
string_t api_path{path};
#if defined(_WIN32)
if ((api_path.size() >= 2U) && (api_path.at(1U) == ':')) {
api_path = api_path.substr(2U);
}
#endif // defined(_WIN32)
while (utils::string::begins_with(api_path, dot_slash_t)) {
api_path = api_path.substr(dot_slash_t.size());
}
while (utils::string::begins_with(api_path, dot_t)) {
api_path = api_path.substr(dot_t.size());
}
format_path(api_path, slash_t, backslash_t);
if (api_path.at(0U) != slash_t.at(0U)) {
return string_t{slash_t} + api_path;
}
return api_path;
}
inline auto create_api_path(std::string_view path) -> std::string {
return create_api_path_t<std::string>(path);
}
inline auto create_api_path(std::wstring_view path) -> std::wstring {
return create_api_path_t<std::wstring>(path);
}
template <typename string_t>
[[nodiscard]] inline auto directory_exists_in_path_t(
std::basic_string_view<typename string_t::value_type> path,
std::basic_string_view<typename string_t::value_type> sub_directory)
-> bool {
return std::filesystem::is_directory(
std::filesystem::path(path).append(sub_directory));
}
inline auto directory_exists_in_path(std::string_view path,
std::string_view sub_directory) -> bool {
return directory_exists_in_path_t<std::string>(path, sub_directory);
}
inline auto directory_exists_in_path(std::wstring_view path,
std::wstring_view sub_directory) -> bool {
return directory_exists_in_path_t<std::wstring>(path, sub_directory);
}
template <typename string_t>
[[nodiscard]] inline auto file_exists_in_path_t(
std::basic_string_view<typename string_t::value_type> path,
std::basic_string_view<typename string_t::value_type> file_name) -> bool {
return std::filesystem::is_regular_file(
std::filesystem::path(path).append(file_name));
}
inline auto file_exists_in_path(std::string_view path,
std::string_view file_name) -> bool {
return file_exists_in_path_t<std::string>(path, file_name);
}
inline auto file_exists_in_path(std::wstring_view path,
std::wstring_view file_name) -> bool {
return file_exists_in_path_t<std::wstring>(path, file_name);
}
template <typename string_t>
[[nodiscard]] inline auto finalize_t(
std::basic_string_view<typename string_t::value_type> path) -> string_t {
string_t fmt_path{path};
format_path(fmt_path,
get_directory_seperator<typename string_t::value_type>(),
get_not_directory_seperator<typename string_t::value_type>());
return fmt_path;
}
inline auto finalize(std::string_view path) -> std::string {
return finalize_t<std::string>(path);
}
inline auto finalize(std::wstring_view path) -> std::wstring {
return finalize_t<std::wstring>(path);
}
template <typename string_t>
inline auto
format_path(string_t &path,
std::basic_string_view<typename string_t::value_type> sep,
std::basic_string_view<typename string_t::value_type> not_sep)
-> string_t & {
utils::string::replace(path, not_sep, sep);
string_t double_sep(2U, sep.at(0U));
while (utils::string::contains(path, double_sep)) {
utils::string::replace(path, double_sep, sep);
}
if (path != sep) {
utils::string::right_trim(path, sep.at(0U));
}
#if defined(_WIN32)
if ((path.size() >= 2U) && (path.at(1U) == ':')) {
path[0U] = utils::string::to_lower(string_t{1U, path.at(0U)}).at(0U);
}
#endif // defined(_WIN32)
return path;
}
template <typename string_t>
[[nodiscard]] inline auto get_parent_api_path_t(
std::basic_string_view<typename string_t::value_type> path) -> string_t {
auto slash_t = get_slash<typename string_t::value_type>();
string_t ret;
if (path == slash_t) {
return ret;
}
ret = path.substr(0, path.rfind('/') + 1);
if (ret == slash_t) {
return ret;
}
return utils::string::right_trim(ret, '/');
}
inline auto get_parent_api_path(std::string_view path) -> std::string {
return get_parent_api_path_t<std::string>(path);
}
inline auto get_parent_api_path(std::wstring_view path) -> std::wstring {
return get_parent_api_path_t<std::wstring>(path);
}
} // namespace repertory::utils::path
#endif // REPERTORY_INCLUDE_UTILS_PATH_HPP_