mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Improve PluginMetadata YAML serialisation
- Move "url" before "group" - Serialise single-element lists using the flow style if their element will be written as a scalar value - Uppercase letters in CRC hex values - Pad CRC hex values so they're always 8 characters long (excluding the 0x prefix).
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#include "api/helpers/crc.h"
|
||||
|
||||
#include <boost/crc.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <fstream>
|
||||
|
||||
#include "api/helpers/logging.h"
|
||||
@@ -81,4 +82,8 @@ uint32_t GetCrc32(const std::filesystem::path& filename) {
|
||||
"\" for CRC calulation: " + e.what());
|
||||
}
|
||||
}
|
||||
|
||||
std::string CrcToString(uint32_t crc) {
|
||||
return (boost::format("%08X") % crc).str();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
namespace loot {
|
||||
uint32_t GetCrc32(const std::filesystem::path& filename);
|
||||
|
||||
std::string CrcToString(uint32_t crc);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -82,12 +82,6 @@ int mapGameType(GameType gameType) {
|
||||
}
|
||||
}
|
||||
|
||||
std::string IntToHexString(const uint32_t value) {
|
||||
std::stringstream stream;
|
||||
stream << std::hex << value;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
ConditionEvaluator::ConditionEvaluator(const GameType gameType,
|
||||
const std::filesystem::path& dataPath) :
|
||||
lciState_(std::unique_ptr<lci_state, decltype(&lci_state_destroy)>(
|
||||
@@ -256,7 +250,7 @@ bool ConditionEvaluator::Evaluate(const PluginCleaningData& cleaningData,
|
||||
return false;
|
||||
|
||||
return Evaluate("checksum(\"" + pluginName + "\", " +
|
||||
IntToHexString(cleaningData.GetCRC()) + ")");
|
||||
CrcToString(cleaningData.GetCRC()) + ")");
|
||||
}
|
||||
|
||||
void ParseCondition(const std::string& condition) {
|
||||
|
||||
@@ -35,6 +35,13 @@
|
||||
#include "api/metadata/yaml/message_content.h"
|
||||
#include "loot/metadata/file.h"
|
||||
|
||||
namespace loot {
|
||||
inline bool emitAsScalar(const File& file) {
|
||||
return !file.IsConditional() && file.GetDetail().empty() &&
|
||||
file.GetDisplayName().empty();
|
||||
}
|
||||
}
|
||||
|
||||
namespace YAML {
|
||||
template<>
|
||||
struct convert<loot::File> {
|
||||
@@ -116,10 +123,9 @@ struct convert<loot::File> {
|
||||
};
|
||||
|
||||
inline Emitter& operator<<(Emitter& out, const loot::File& rhs) {
|
||||
if (!rhs.IsConditional() && rhs.GetDetail().empty() &&
|
||||
rhs.GetDisplayName().empty())
|
||||
if (loot::emitAsScalar(rhs)) {
|
||||
out << YAML::SingleQuoted << std::string(rhs.GetName());
|
||||
else {
|
||||
} else {
|
||||
out << BeginMap << Key << "name" << Value << YAML::SingleQuoted
|
||||
<< std::string(rhs.GetName());
|
||||
|
||||
|
||||
@@ -33,6 +33,12 @@
|
||||
|
||||
#include "loot/metadata/location.h"
|
||||
|
||||
namespace loot {
|
||||
inline bool emitAsScalar(const Location& location) {
|
||||
return location.GetName().empty();
|
||||
}
|
||||
}
|
||||
|
||||
namespace YAML {
|
||||
template<>
|
||||
struct convert<loot::Location> {
|
||||
@@ -74,9 +80,9 @@ struct convert<loot::Location> {
|
||||
};
|
||||
|
||||
inline Emitter& operator<<(Emitter& out, const loot::Location& rhs) {
|
||||
if (rhs.GetName().empty())
|
||||
if (emitAsScalar(rhs)) {
|
||||
out << YAML::SingleQuoted << rhs.GetURL();
|
||||
else {
|
||||
} else {
|
||||
out << BeginMap << Key << "link" << Value << YAML::SingleQuoted
|
||||
<< rhs.GetURL() << Key << "name" << Value << YAML::SingleQuoted
|
||||
<< rhs.GetName() << EndMap;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "api/helpers/crc.h"
|
||||
#include "loot/metadata/plugin_cleaning_data.h"
|
||||
|
||||
namespace YAML {
|
||||
@@ -109,8 +110,9 @@ struct convert<loot::PluginCleaningData> {
|
||||
};
|
||||
|
||||
inline Emitter& operator<<(Emitter& out, const loot::PluginCleaningData& rhs) {
|
||||
out << BeginMap << Key << "crc" << Value << Hex << rhs.GetCRC() << Dec << Key
|
||||
<< "util" << Value << YAML::SingleQuoted << rhs.GetCleaningUtility();
|
||||
out << BeginMap << Key << "crc" << Value
|
||||
<< "0x" + loot::CrcToString(rhs.GetCRC()) << Key << "util" << Value
|
||||
<< YAML::SingleQuoted << rhs.GetCleaningUtility();
|
||||
|
||||
if (!rhs.GetDetail().empty()) {
|
||||
if (rhs.GetDetail().size() == 1)
|
||||
|
||||
@@ -44,6 +44,17 @@
|
||||
#include "api/metadata/yaml/tag.h"
|
||||
#include "loot/metadata/plugin_metadata.h"
|
||||
|
||||
namespace loot {
|
||||
template<typename T>
|
||||
inline ::YAML::EMITTER_MANIP getNodeStyle(const std::vector<T>& objects) {
|
||||
if (objects.size() == 1 && emitAsScalar(objects.at(0))) {
|
||||
return YAML::Flow;
|
||||
}
|
||||
|
||||
return YAML::Block;
|
||||
}
|
||||
}
|
||||
|
||||
namespace YAML {
|
||||
template<>
|
||||
struct convert<loot::PluginMetadata> {
|
||||
@@ -126,24 +137,39 @@ inline Emitter& operator<<(Emitter& out, const loot::PluginMetadata& rhs) {
|
||||
out << BeginMap << Key << "name" << Value << YAML::SingleQuoted
|
||||
<< rhs.GetName();
|
||||
|
||||
if (rhs.GetGroup())
|
||||
const auto locations = rhs.GetLocations();
|
||||
if (!locations.empty()) {
|
||||
out << Key << "url" << Value << loot::getNodeStyle(locations)
|
||||
<< locations;
|
||||
}
|
||||
|
||||
if (rhs.GetGroup()) {
|
||||
out << Key << "group" << Value << YAML::SingleQuoted
|
||||
<< rhs.GetGroup().value();
|
||||
}
|
||||
|
||||
if (!rhs.GetLoadAfterFiles().empty())
|
||||
out << Key << "after" << Value << rhs.GetLoadAfterFiles();
|
||||
const auto after = rhs.GetLoadAfterFiles();
|
||||
if (!after.empty()) {
|
||||
out << Key << "after" << Value << loot::getNodeStyle(after) << after;
|
||||
}
|
||||
|
||||
if (!rhs.GetRequirements().empty())
|
||||
out << Key << "req" << Value << rhs.GetRequirements();
|
||||
const auto req = rhs.GetRequirements();
|
||||
if (!req.empty()) {
|
||||
out << Key << "req" << Value << loot::getNodeStyle(req) << req;
|
||||
}
|
||||
|
||||
if (!rhs.GetIncompatibilities().empty())
|
||||
out << Key << "inc" << Value << rhs.GetIncompatibilities();
|
||||
const auto inc = rhs.GetIncompatibilities();
|
||||
if (!inc.empty()) {
|
||||
out << Key << "inc" << Value << loot::getNodeStyle(inc) << inc;
|
||||
}
|
||||
|
||||
if (!rhs.GetMessages().empty())
|
||||
out << Key << "msg" << Value << rhs.GetMessages();
|
||||
|
||||
if (!rhs.GetTags().empty())
|
||||
out << Key << "tag" << Value << rhs.GetTags();
|
||||
const auto tags = rhs.GetTags();
|
||||
if (!tags.empty()) {
|
||||
out << Key << "tag" << Value << loot::getNodeStyle(tags) << tags;
|
||||
}
|
||||
|
||||
if (!rhs.GetDirtyInfo().empty())
|
||||
out << Key << "dirty" << Value << rhs.GetDirtyInfo();
|
||||
@@ -151,9 +177,6 @@ inline Emitter& operator<<(Emitter& out, const loot::PluginMetadata& rhs) {
|
||||
if (!rhs.GetCleanInfo().empty())
|
||||
out << Key << "clean" << Value << rhs.GetCleanInfo();
|
||||
|
||||
if (!rhs.GetLocations().empty())
|
||||
out << Key << "url" << Value << rhs.GetLocations();
|
||||
|
||||
out << EndMap;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
#include "api/metadata/condition_evaluator.h"
|
||||
#include "loot/metadata/tag.h"
|
||||
|
||||
namespace loot {
|
||||
inline bool emitAsScalar(const Tag& tag) { return !tag.IsConditional(); }
|
||||
}
|
||||
|
||||
namespace YAML {
|
||||
template<>
|
||||
struct convert<loot::Tag> {
|
||||
@@ -84,7 +88,7 @@ struct convert<loot::Tag> {
|
||||
};
|
||||
|
||||
inline Emitter& operator<<(Emitter& out, const loot::Tag& rhs) {
|
||||
if (!rhs.IsConditional()) {
|
||||
if (emitAsScalar(rhs)) {
|
||||
if (rhs.IsAddition())
|
||||
out << rhs.GetName();
|
||||
else
|
||||
|
||||
@@ -50,7 +50,7 @@ protected:
|
||||
expectedContent << "plugins:" << endl
|
||||
<< " - name: '" << blankDifferentEsm << "'" << endl
|
||||
<< " dirty:" << endl
|
||||
<< " - crc: 0x7d22f9df" << endl
|
||||
<< " - crc: 0x7D22F9DF" << endl
|
||||
<< " util: 'TES4Edit'" << endl
|
||||
<< " udr: 4" << endl
|
||||
<< " - name: '" << blankEsm << "'" << endl
|
||||
|
||||
@@ -394,8 +394,7 @@ TEST_P(PluginMetadataTest,
|
||||
|
||||
EXPECT_EQ(
|
||||
"name: 'Blank.esm'\n"
|
||||
"after:\n"
|
||||
" - 'Blank.esm'",
|
||||
"after: ['Blank.esm']",
|
||||
plugin.AsYaml());
|
||||
}
|
||||
|
||||
@@ -418,8 +417,7 @@ TEST_P(PluginMetadataTest,
|
||||
|
||||
EXPECT_STREQ(
|
||||
"name: 'Blank.esm'\n"
|
||||
"after:\n"
|
||||
" - 'Blank.esm'",
|
||||
"after: ['Blank.esm']",
|
||||
emitter.c_str());
|
||||
}
|
||||
|
||||
@@ -447,8 +445,7 @@ TEST_P(PluginMetadataTest,
|
||||
|
||||
EXPECT_STREQ(
|
||||
"name: 'Blank.esp'\n"
|
||||
"after:\n"
|
||||
" - 'Blank.esm'",
|
||||
"after: ['Blank.esm']",
|
||||
emitter.c_str());
|
||||
}
|
||||
|
||||
@@ -462,8 +459,7 @@ TEST_P(PluginMetadataTest,
|
||||
|
||||
EXPECT_STREQ(
|
||||
"name: 'Blank.esp'\n"
|
||||
"req:\n"
|
||||
" - 'Blank.esm'",
|
||||
"req: ['Blank.esm']",
|
||||
emitter.c_str());
|
||||
}
|
||||
|
||||
@@ -477,8 +473,7 @@ TEST_P(PluginMetadataTest,
|
||||
|
||||
EXPECT_STREQ(
|
||||
"name: 'Blank.esp'\n"
|
||||
"inc:\n"
|
||||
" - 'Blank.esm'",
|
||||
"inc: ['Blank.esm']",
|
||||
emitter.c_str());
|
||||
}
|
||||
|
||||
@@ -507,8 +502,7 @@ TEST_P(PluginMetadataTest, emittingAsYamlShouldOutputAPluginWithTagsCorrectly) {
|
||||
|
||||
EXPECT_STREQ(
|
||||
"name: 'Blank.esp'\n"
|
||||
"tag:\n"
|
||||
" - Relev",
|
||||
"tag: [Relev]",
|
||||
emitter.c_str());
|
||||
}
|
||||
|
||||
@@ -523,7 +517,7 @@ TEST_P(PluginMetadataTest,
|
||||
EXPECT_STREQ(
|
||||
"name: 'Blank.esp'\n"
|
||||
"dirty:\n"
|
||||
" - crc: 0x5\n"
|
||||
" - crc: 0x00000005\n"
|
||||
" util: 'utility'\n"
|
||||
" detail: 'info'\n"
|
||||
" udr: 1\n"
|
||||
@@ -542,7 +536,7 @@ TEST_P(PluginMetadataTest,
|
||||
EXPECT_STREQ(
|
||||
"name: 'Blank.esp'\n"
|
||||
"clean:\n"
|
||||
" - crc: 0x5\n"
|
||||
" - crc: 0x00000005\n"
|
||||
" util: 'utility'",
|
||||
emitter.c_str());
|
||||
}
|
||||
@@ -557,8 +551,7 @@ TEST_P(PluginMetadataTest,
|
||||
|
||||
EXPECT_STREQ(
|
||||
"name: 'Blank.esp'\n"
|
||||
"url:\n"
|
||||
" - 'http://www.example.com'",
|
||||
"url: ['http://www.example.com']",
|
||||
emitter.c_str());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user