mirror of
https://github.com/sebastiandine/Card-Collection-Manager-3.git
synced 2026-08-30 03:01:25 +00:00
85 lines
2.3 KiB
C++
85 lines
2.3 KiB
C++
#include "ccm/util/FsNames.hpp"
|
|
|
|
#include <algorithm>
|
|
#include <array>
|
|
#include <cctype>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <utility>
|
|
|
|
namespace ccm {
|
|
|
|
namespace {
|
|
|
|
// Replacements ordered exactly like the Rust source's chained .replace(...) so
|
|
// behavior is bit-identical for inputs that contain multiple of these chars.
|
|
struct Replacement {
|
|
std::string_view from;
|
|
std::string_view to;
|
|
};
|
|
|
|
constexpr std::array<Replacement, 14> kReplacements{{
|
|
{"'", ""},
|
|
{"`", ""},
|
|
{",", ""},
|
|
{" ", ""},
|
|
{":", "-"},
|
|
{"&", "And"},
|
|
{"|", "Or"},
|
|
{"\xC3\xA1", "a"}, // a-acute (UTF-8)
|
|
{"\xC3\xA9", "e"}, // e-acute
|
|
{"\xC3\xAD", "i"}, // i-acute
|
|
{"\xC3\xB3", "o"}, // o-acute
|
|
{"\xC3\xBA", "u"}, // u-acute
|
|
{"\xC3\xBB", "u"}, // u-circumflex
|
|
// Remaining accented vowels appear in modern Scryfall data but were not
|
|
// listed in the Rust source. Keeping behavior 1:1 deliberately.
|
|
}};
|
|
|
|
void replaceAllInPlace(std::string& s, std::string_view from, std::string_view to) {
|
|
if (from.empty()) return;
|
|
std::string::size_type pos = 0;
|
|
while ((pos = s.find(from, pos)) != std::string::npos) {
|
|
s.replace(pos, from.size(), to);
|
|
pos += to.size();
|
|
}
|
|
}
|
|
|
|
} // namespace
|
|
|
|
std::string formatTextForFs(std::string_view text) {
|
|
std::string out(text);
|
|
for (const auto& r : kReplacements) {
|
|
replaceAllInPlace(out, r.from, r.to);
|
|
}
|
|
return out;
|
|
}
|
|
|
|
std::uint8_t parseIndexFromFilename(std::string_view filename) noexcept {
|
|
const auto dot = filename.find_last_of('.');
|
|
if (dot == std::string_view::npos || dot == 0) return 0;
|
|
|
|
// Walk backwards from the position before the dot, collecting digits.
|
|
std::size_t end = dot;
|
|
std::size_t begin = end;
|
|
while (begin > 0) {
|
|
unsigned char ch = static_cast<unsigned char>(filename[begin - 1]);
|
|
if (std::isdigit(ch)) {
|
|
--begin;
|
|
// Rust source intentionally caps at 2-digit indices.
|
|
if (end - begin >= 2) break;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
if (begin == end) return 0;
|
|
|
|
unsigned int value = 0;
|
|
for (std::size_t i = begin; i < end; ++i) {
|
|
value = value * 10 + static_cast<unsigned int>(filename[i] - '0');
|
|
}
|
|
return static_cast<std::uint8_t>(value);
|
|
}
|
|
|
|
} // namespace ccm
|