15 const std::string &tileset_name,
17 const ConfigValue<std::vector<std::string>> &partners,
24 std::string partner_name{};
26 switch (pairing_mode.
value()) {
28 if (!partners.value().empty()) {
30 "pairing-partners-ignored",
31 std::vector<std::string>{
33 "Primary pairing mode is 'off' but '{}' has non-empty pairing partners list.",
35 "Partners will be ignored."});
37 return std::unique_ptr<Tileset>{
nullptr};
41 if (partners.value().empty()) {
42 std::vector<std::string> err_msg{};
44 "Primary pairing mode is 'manual' but no partner primaries configured for '{}'.",
50 partner_name = partners.value().at(0);
55 if (!partners.value().empty()) {
56 constexpr auto warn_tag =
"pairing-partners-ignored";
59 std::vector<std::string>{
61 "Primary pairing mode is 'automatic' but '{}' has non-empty pairing partners list.",
63 "Partners will be ignored."});
64 std::vector<std::string> note_lines{};
73 std::unique_ptr<Tileset>,
74 "Failed to enumerate layouts for automatic primary pairing.");
76 std::set<std::string> found_primaries{};
77 for (
const auto &layout_name : layout_names) {
79 if (!secondary_result.has_value()) {
82 if (secondary_result.value() == tileset_name) {
83 auto primary_result = layout_metadata_provider->
primary_tileset(layout_name);
84 if (primary_result.has_value()) {
85 found_primaries.insert(primary_result.value());
90 if (found_primaries.empty()) {
92 "Automatic primary pairing found no layouts using secondary tileset '{}'.",
96 if (found_primaries.size() > 1) {
97 std::vector<std::string> warn_lines{};
99 "Multiple distinct partner primaries found for '{}' via layout data.",
103 warn_lines.emplace_back(
"Other partners:");
104 for (
const auto &name : found_primaries | std::views::drop(1)) {
107 diag->
warning(
"multiple-partner-primaries", warn_lines);
110 partner_name = *found_primaries.begin();
115 if (!metadata_provider->
exists(partner_name)) {
116 std::vector<std::string> err_msg{};
118 "Resolved partner primary '{}' for secondary '{}' does not exist.",
121 err_msg.emplace_back(
"Create it first or pair with a different tileset.");
127 std::vector<std::string> err_msg{};
129 "Secondary compilation requires a Porytiles-managed primary, but '{}' is not Porytiles-managed.",
131 err_msg.emplace_back(
"Import it first or pair with a different tileset.");
137 constexpr auto tag =
"resolve-partner-primary";
140 "Resolved partner primary '{}' for secondary '{}'.",
143 std::vector<std::string> note_lines{};
150 tileset_repo->
load(partner_name),
151 std::unique_ptr<Tileset>,
152 "Failed to load partner primary '{}' for secondary '{}'.",
156 return primary_tileset;
#define PT_TRY_ASSIGN_CHAIN_ERR(var, expr, return_type,...)
Unwraps a ChainableResult, chaining a new error message on failure.
A result type that maintains a chainable sequence of errors for debugging and error reporting.
A container that wraps a configuration value with its name and source information.
const T & value() const &
Abstract interface for querying Porytiles tileset ownership.
virtual bool is_porytiles_managed(const std::string &tileset_name) const =0
Checks whether a tileset is managed by Porytiles.
static const Style bold
Bold text formatting.
virtual std::string format(const std::string &format_str, const std::vector< FormatParam > ¶ms) const
Formats a string with styled parameters using fmtlib syntax.
Repository interface for the Tileset aggregate root.
ChainableResult< std::unique_ptr< Tileset > > load(const std::string &name) const
Loads an existing Tileset from storage.
Abstract class for structured error reporting and diagnostic output.
virtual void warning_note(const std::string &tag, const std::vector< std::string > &lines) const =0
Display a tagged note message associated with a warning.
virtual void remark(const std::string &tag, const std::vector< std::string > &lines) const =0
Display a tagged remark message.
const TextFormatter & formatter() const
virtual void warning(const std::string &tag, const std::vector< std::string > &lines) const =0
Display a tagged warning message.
virtual void remark_note(const std::string &tag, const std::vector< std::string > &lines) const =0
Display a tagged note message associated with a remark.
@ automatic
Scan layout metadata to find the partner primary automatically.
@ off
Skip primary loading entirely. Compile as a standalone secondary.
@ manual
Use the partner primary specified via primary_pairing_partners config.
ChainableResult< std::unique_ptr< Tileset > > resolve_partner_primary(const std::string &tileset_name, const ConfigValue< PrimaryPairingMode > &pairing_mode, const ConfigValue< std::vector< std::string > > &partners, const TilesetRepo *tileset_repo, const TilesetMetadataProvider *metadata_provider, const LayoutMetadataProvider *layout_metadata_provider, const PorytilesTilesetManager *tileset_manager, const UserDiagnostics *diag)
Resolves the partner primary tileset for a secondary tileset.
std::vector< std::string > format_config_note(const TextFormatter &format, const ConfigValue< T > &config)
Format a ConfigValue into diagnostic note lines.
std::vector< std::string > format_config_note_with_separator(const TextFormatter &format, const ConfigValue< T > &config)
Format a ConfigValue into diagnostic note lines with a separator.