From 4f24a1bc1ded7e1b50ef76204c7e3fc8cfda8c52 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 27 Sep 2025 22:04:25 -0500 Subject: [PATCH] refactor drive letter --- repertory/repertory/src/ui/ui_server.cpp | 21 +------- .../include/fixtures/drive_fixture.hpp | 4 +- support/include/utils/windows.hpp | 6 +++ support/src/utils/windows.cpp | 49 +++++++++++++++++++ 4 files changed, 60 insertions(+), 20 deletions(-) diff --git a/repertory/repertory/src/ui/ui_server.cpp b/repertory/repertory/src/ui/ui_server.cpp index 5f1b0c90..eeaa1f56 100644 --- a/repertory/repertory/src/ui/ui_server.cpp +++ b/repertory/repertory/src/ui/ui_server.cpp @@ -431,25 +431,8 @@ void ui_server::handle_put_mount_location(const httplib::Request &req, void ui_server::handle_get_available_locations(httplib::Response &res) { #if defined(_WIN32) - constexpr std::array letters{ - "a:", "b:", "c:", "d:", "e:", "f:", "g:", "h:", "i:", - "j:", "k:", "l:", "m:", "n:", "o:", "p:", "q:", "r:", - "s:", "t:", "u:", "v:", "w:", "x:", "y:", "z:", - }; - - auto available = std::accumulate( - letters.begin(), letters.end(), std::vector(), - [](auto &&vec, auto &&letter) -> std::vector { - if (utils::file::directory{utils::path::combine(letter, {"\\"})} - .exists()) { - return vec; - } - - vec.emplace_back(letter); - return vec; - }); - - res.set_content(nlohmann::json(available).dump(), "application/json"); + res.set_content(nlohmann::json(utils::get_available_drive_letters()).dump(), + "application/json"); #else // !defined(_WIN32) res.set_content(nlohmann::json(std::vector()).dump(), "application/json"); diff --git a/repertory/repertory_test/include/fixtures/drive_fixture.hpp b/repertory/repertory_test/include/fixtures/drive_fixture.hpp index 10c736f7..81660233 100644 --- a/repertory/repertory_test/include/fixtures/drive_fixture.hpp +++ b/repertory/repertory_test/include/fixtures/drive_fixture.hpp @@ -332,7 +332,9 @@ protected: mount_location2 = mount_location; #if defined(_WIN32) - mount_location = utils::string::to_lower(std::string{"V:"}); + auto letter = utils::get_available_drive_letter('d'); + ASSERT_TRUE(letter.has_value()); + mount_location = utils::string::to_lower(std::string{letter.value()}); #else // !defined(_WIN32) mount_location = utils::path::combine(test_dir, {"mount"}); ASSERT_TRUE(utils::file::directory(mount_location).create_directory()); diff --git a/support/include/utils/windows.hpp b/support/include/utils/windows.hpp index 2cc95865..53b12e77 100644 --- a/support/include/utils/windows.hpp +++ b/support/include/utils/windows.hpp @@ -30,6 +30,12 @@ void create_console(); void free_console(); +[[nodiscard]] auto get_available_drive_letter(char first = 'a') + -> std::optional; + +[[nodiscard]] auto get_available_drive_letters(char first = 'a') + -> std::vector; + [[nodiscard]] auto get_local_app_data_directory() -> const std::string &; [[nodiscard]] auto get_last_error_code() -> DWORD; diff --git a/support/src/utils/windows.cpp b/support/src/utils/windows.cpp index 66ca722f..cbfffa85 100644 --- a/support/src/utils/windows.cpp +++ b/support/src/utils/windows.cpp @@ -29,6 +29,14 @@ #include "utils/path.hpp" #include "utils/string.hpp" +namespace { +constexpr std::array drive_letters{ + "a:", "b:", "c:", "d:", "e:", "f:", "g:", "h:", "i:", + "j:", "k:", "l:", "m:", "n:", "o:", "p:", "q:", "r:", + "s:", "t:", "u:", "v:", "w:", "x:", "y:", "z:", +}; +} + namespace repertory::utils { void create_console() { if (::AllocConsole() == 0) { @@ -61,6 +69,47 @@ void create_console() { void free_console() { ::FreeConsole(); } +auto get_available_drive_letter(char first) -> std::optional { + const auto *begin = std::ranges::find_if( + drive_letters, [first](auto &&val) { return val.at(0U) == first; }); + if (begin == drive_letters.end()) { + begin = drive_letters.begin(); + } + + auto available = + std::ranges::find_if(begin, drive_letters.end(), [](auto &&val) -> bool { + return not utils::file::directory{utils::path::combine(val, {"\\"})} + .exists(); + }); + if (available == drive_letters.end()) { + return std::nullopt; + } + + return *available; +} + +auto get_available_drive_letters(char first) -> std::vector { + const auto *begin = + std::ranges::find_if(drive_letters, [first](auto &&val) -> bool { + return val.at(0U) == first; + }); + if (begin == drive_letters.end()) { + begin = drive_letters.begin(); + } + + return std::accumulate( + begin, drive_letters.end(), std::vector(), + [](auto &&vec, auto &&letter) -> auto { + if (utils::file::directory{utils::path::combine(letter, {"\\"})} + .exists()) { + return vec; + } + + vec.emplace_back(letter); + return vec; + }); +} + auto get_last_error_code() -> DWORD { return ::GetLastError(); } auto get_local_app_data_directory() -> const std::string & {