mirror of
https://github.com/sebastiandine/Card-Collection-Manager-3.git
synced 2026-08-31 18:01:23 +00:00
major: initial release
* initial development * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * ci/cd * ci/cd * ci/cd * ci/cd * ci/cd * ci/cd * ci/cd * pokemon * pokemon * pokemon * pokemon * pokemon * pokemon * improvements * improvements * ci/cd * ci/cd * improvements * improvements * improvements * improvements * improvements * improvements * improvements * improvements * improvements --------- Co-authored-by: sdine <sdine@sdine.com>
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
#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');
|
||||
}
|
||||
if (value > 255) value = 255;
|
||||
return static_cast<std::uint8_t>(value);
|
||||
}
|
||||
|
||||
} // namespace ccm
|
||||
Reference in New Issue
Block a user