Files
SpineParticlesWeb/DateToSpine/src/domain/SpineVersion.cpp
T
2026-09-07 21:29:15 +08:00

72 lines
2.1 KiB
C++

#include "domain/SpineVersion.hpp"
#include <charconv>
namespace dts {
namespace {
std::optional<int> parseNumber(std::string_view text) {
int value = 0;
const auto result = std::from_chars(text.data(), text.data() + text.size(), value);
if (result.ec != std::errc{} || result.ptr != text.data() + text.size()) {
return std::nullopt;
}
return value;
}
} // namespace
std::optional<SpineVersion> SpineVersion::parse(std::string_view text) {
const auto firstDot = text.find('.');
if (firstDot == std::string_view::npos) {
return std::nullopt;
}
const auto secondDot = text.find('.', firstDot + 1);
const auto majorValue = parseNumber(text.substr(0, firstDot));
const auto minorEnd = secondDot == std::string_view::npos ? text.size() : secondDot;
const auto minorValue = parseNumber(text.substr(firstDot + 1, minorEnd - firstDot - 1));
if (!majorValue || !minorValue) {
return std::nullopt;
}
SpineVersion version{*majorValue, *minorValue, 0, false};
if (secondDot != std::string_view::npos) {
auto patchText = text.substr(secondDot + 1);
const auto suffix = patchText.find_first_not_of("0123456789");
const auto numericPatch = patchText.substr(0, suffix);
if (numericPatch.empty() || (suffix != std::string_view::npos
&& patchText[suffix] != '-')) {
return std::nullopt;
}
const auto patchValue = parseNumber(numericPatch);
if (!patchValue) {
return std::nullopt;
}
version.patch = *patchValue;
version.hasPatch = true;
}
return version;
}
std::string SpineVersion::line() const {
return std::to_string(major) + "." + std::to_string(minor);
}
std::string SpineVersion::toString() const {
auto value = line();
if (hasPatch) {
value += "." + std::to_string(patch);
}
return value;
}
bool SpineVersion::isSupported() const {
if (major == 3 && minor == 8) {
return !hasPatch || patch >= 20;
}
return major == 4 && minor >= 0 && minor <= 3;
}
} // namespace dts