72 lines
2.1 KiB
C++
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
|