Added JSON test cases for all sequence diagram test cases

This commit is contained in:
Bartek Kryza
2023-03-25 01:25:27 +01:00
parent 49a40723a7
commit 43b81f97ce
27 changed files with 345 additions and 32 deletions

View File

@@ -18,12 +18,23 @@
#include "sequence_diagram_generator.h"
namespace clanguml::sequence_diagram::generators::json {
std::string render_name(std::string name)
{
util::replace_all(name, "##", "::");
return name;
}
} // namespace clanguml::sequence_diagram::generators::json
namespace clanguml::sequence_diagram::model {
using nlohmann::json;
// using nlohmann::json;
void to_json(nlohmann::json &j, const participant &c)
{
j["name"] = c.full_name(false);
j["name"] = generators::json::render_name(c.full_name(false));
j["id"] = std::to_string(c.id());
j["type"] = c.type_name();
if (!c.file().empty())
@@ -95,7 +106,8 @@ void generator::generate_call(const message &m, nlohmann::json &parent) const
msg["name"] = message;
msg["type"] = "message";
msg["from"]["activity_name"] = from.value().full_name(false);
msg["from"]["activity_name"] =
generators::json::render_name(from.value().full_name(false));
msg["from"]["activity_id"] = std::to_string(from.value().id());
msg["to"]["activity_id"] = std::to_string(to.value().id());
msg["to"]["activity_name"] = to.value().full_name(false);
@@ -106,10 +118,10 @@ void generator::generate_call(const message &m, nlohmann::json &parent) const
msg["from"]["participant_id"] =
std::to_string(class_participant.class_id());
msg["from"]["participant_name"] =
msg["from"]["participant_name"] = generators::json::render_name(
m_model.get_participant<model::class_>(class_participant.class_id())
.value()
.full_name(false);
.full_name(false));
}
else if (from.value().type_name() == "function" ||
from.value().type_name() == "function_template") {
@@ -118,14 +130,22 @@ void generator::generate_call(const message &m, nlohmann::json &parent) const
m_model.get_participant<model::function>(from.value().id())
.value();
msg["from"]["participant_id"] =
std::to_string(common::to_id(file_participant.file()));
msg["from"]["participant_name"] = file_participant.file_relative();
std::to_string(common::to_id(file_participant.file_relative()));
msg["from"]["participant_name"] = util::path_to_url(
std::filesystem::relative(file_participant.file(),
std::filesystem::canonical(m_config.relative_to())
.string()));
}
else {
msg["from"]["participant_id"] = std::to_string(from.value().id());
msg["from"]["participant_name"] = from.value().full_name(false);
}
}
else if (from.value().type_name() == "lambda") {
msg["from"]["participant_id"] = std::to_string(from.value().id());
msg["from"]["participant_name"] =
generators::json::render_name(from.value().full_name(false));
}
if (to.value().type_name() == "method") {
const auto &class_participant =
@@ -145,14 +165,22 @@ void generator::generate_call(const message &m, nlohmann::json &parent) const
m_model.get_participant<model::function>(to.value().id())
.value();
msg["to"]["participant_id"] =
std::to_string(common::to_id(file_participant.file()));
msg["to"]["participant_name"] = file_participant.file_relative();
std::to_string(common::to_id(file_participant.file_relative()));
msg["to"]["participant_name"] = util::path_to_url(
std::filesystem::relative(file_participant.file(),
std::filesystem::canonical(m_config.relative_to())
.string()));
}
else {
msg["to"]["participant_id"] = std::to_string(to.value().id());
msg["to"]["participant_name"] = to.value().full_name(false);
}
}
else if (to.value().type_name() == "lambda") {
msg["to"]["participant_id"] = std::to_string(to.value().id());
msg["to"]["participant_name"] =
generators::json::render_name(to.value().full_name(false));
}
msg["source_location"] =
dynamic_cast<const clanguml::common::model::source_location &>(m);
@@ -339,10 +367,10 @@ void generator::process_try_message(const message &m) const
nlohmann::json branch;
branch["type"] = "main";
current_block_statement()["blocks"].push_back(std::move(branch));
current_block_statement()["branches"].push_back(std::move(branch));
block_statements_stack_.push_back(
std::ref(current_block_statement()["blocks"].back()));
std::ref(current_block_statement()["branches"].back()));
}
void generator::process_catch_message() const
@@ -352,10 +380,10 @@ void generator::process_catch_message() const
nlohmann::json branch;
branch["type"] = "catch";
current_block_statement()["blocks"].push_back(std::move(branch));
current_block_statement()["branches"].push_back(std::move(branch));
block_statements_stack_.push_back(
std::ref(current_block_statement()["blocks"].back()));
std::ref(current_block_statement()["branches"].back()));
}
void generator::process_end_try_message() const
@@ -388,10 +416,10 @@ void generator::process_case_message(const message &m) const
nlohmann::json case_block;
case_block["type"] = "case";
case_block["name"] = m.message_name();
current_block_statement()["cases"].push_back(std::move(case_block));
current_block_statement()["branches"].push_back(std::move(case_block));
block_statements_stack_.push_back(
std::ref(current_block_statement()["cases"].back()));
std::ref(current_block_statement()["branches"].back()));
}
void generator::process_end_switch_message() const
@@ -526,20 +554,17 @@ common::id_t generator::generate_participant(
m_model.get_participant<model::participant>(participant_id).value();
if (participant.type_name() == "method") {
const auto class_id =
m_model.get_participant<model::method>(participant_id)
.value()
.class_id();
participant_id = m_model.get_participant<model::method>(participant_id)
.value()
.class_id();
if (is_participant_generated(class_id))
if (is_participant_generated(participant_id))
return participant_id;
const auto &class_participant =
m_model.get_participant<model::participant>(class_id).value();
m_model.get_participant<model::participant>(participant_id).value();
parent["participants"].push_back(class_participant);
generated_participants_.emplace(class_id);
}
else if ((participant.type_name() == "function" ||
participant.type_name() == "function_template") &&
@@ -549,17 +574,26 @@ common::id_t generator::generate_participant(
const auto &function_participant =
m_model.get_participant<model::function>(participant_id).value();
parent["participants"].push_back(function_participant);
nlohmann::json j = function_participant;
j["name"] = util::path_to_url(
std::filesystem::relative(function_participant.file(),
std::filesystem::canonical(m_config.relative_to()).string()));
generated_participants_.emplace(
common::to_id(function_participant.file()));
participant_id = common::to_id(function_participant.file_relative());
if (is_participant_generated(participant_id))
return participant_id;
j["id"] = std::to_string(participant_id);
parent["participants"].push_back(j);
}
else {
parent["participants"].push_back(participant);
generated_participants_.emplace(participant_id);
}
generated_participants_.emplace(participant_id);
return participant_id;
}

View File

@@ -32,6 +32,8 @@
namespace clanguml::sequence_diagram::generators::json {
std::string render_name(std::string name);
using diagram_config = clanguml::config::sequence_diagram;
using diagram_model = clanguml::sequence_diagram::model::diagram;

View File

@@ -50,6 +50,11 @@ TEST_CASE("t20005", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {FindMessage(j, "C<T>", "B<T>", "b(T)"),
FindMessage(j, "B<T>", "A<T>", "a(T)")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -83,6 +83,17 @@ TEST_CASE("t20006", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {
FindMessage(j, "tmain()", "B<int>", "b(int)"),
FindMessage(j, "B<int>", "A<int>", "a1(int)"),
FindMessage(j, "tmain()", "B<std::string>", "b(std::string)"),
FindMessage(j, "tmain()", "BB<int,int>", "bb1(int,int)"),
FindMessage(j, "BB<int,int>", "AA<int>", "aa1(int)"),
FindMessage(
j, "tmain()", "BB<int,std::string>", "bb1(int,std::string)")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -54,6 +54,16 @@ TEST_CASE("t20007", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {
FindMessage(j, "tmain()", "Adder<int,int>", "add(int &&,int &&)"),
FindMessage(j, "tmain()", "Adder<int,float,double>",
"add(int &&,float &&,double &&)"),
FindMessage(j, "tmain()",
"Adder<std::string,std::string,std::string>",
"add(std::string &&,std::string &&,std::string &&)")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -62,6 +62,18 @@ TEST_CASE("t20008", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {
FindMessage(j, "tmain()", "B<int>", "b(int)"),
FindMessage(j, "B<int>", "A<int>", "a1(int)"),
FindMessage(j, "tmain()", "B<const char *>", "b(const char *)"),
FindMessage(
j, "B<const char *>", "A<const char *>", "a2(const char *)"),
FindMessage(j, "tmain()", "B<std::string>", "b(std::string)"),
FindMessage(
j, "B<std::string>", "A<std::string>", "a3(std::string)")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -55,6 +55,17 @@ TEST_CASE("t20009", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {
FindMessage(j, "tmain()", "B<std::string>", "b(std::string)"),
FindMessage(
j, "B<std::string>", "A<std::string>", "a(std::string)"),
FindMessage(j, "tmain()", "B<int>", "b(int)"),
FindMessage(j, "B<int>", "A<int>", "a(int)"),
FindMessage(j, "tmain()", "B<float>", "b(float)"),
FindMessage(j, "B<float>", "A<float>", "a(float)")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -56,6 +56,18 @@ TEST_CASE("t20010", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {
FindMessage(j, "tmain()", "B<int>", "b1()"),
FindMessage(j, "B<int>", "A", "a1()"),
FindMessage(j, "tmain()", "B<int>", "b2()"),
FindMessage(j, "B<int>", "A", "a2()"),
FindMessage(j, "tmain()", "B<int>", "b3()"),
FindMessage(j, "B<int>", "A", "a3()"),
FindMessage(j, "tmain()", "B<int>", "b4()"),
FindMessage(j, "B<int>", "A", "a4()")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -85,6 +85,38 @@ TEST_CASE("t20012", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {
FindMessage(j, "tmain()",
"tmain()::(lambda ../../tests/t20012/t20012.cc:66:20)",
"operator()()"),
FindMessage(j,
"tmain()::(lambda ../../tests/t20012/t20012.cc:66:20)", "A",
"a()"),
FindMessage(j, "A", "A", "aa()"), FindMessage(j, "A", "A", "aaa()"),
FindMessage(j,
"tmain()::(lambda ../../tests/t20012/t20012.cc:66:20)", "B",
"b()"),
FindMessage(j, "B", "B", "bb()"), FindMessage(j, "B", "B", "bbb()"),
FindMessage(j,
"tmain()::(lambda ../../tests/t20012/t20012.cc:79:20)", "C",
"c()"),
FindMessage(j, "C", "C", "cc()"), FindMessage(j, "C", "C", "ccc()"),
FindMessage(j,
"tmain()::(lambda ../../tests/t20012/t20012.cc:79:20)",
"tmain()::(lambda ../../tests/t20012/t20012.cc:66:20)",
"operator()()"),
FindMessage(j, "tmain()",
"R<R::(lambda ../../tests/t20012/t20012.cc:85:9)>", "r()"),
FindMessage(j, "R<R::(lambda ../../tests/t20012/t20012.cc:85:9)>",
"tmain()::(lambda ../../tests/t20012/t20012.cc:85:9)",
"operator()()"),
FindMessage(j,
"tmain()::(lambda ../../tests/t20012/t20012.cc:85:9)", "C",
"c()"),
FindMessage(j, "tmain()", "D", "add5(int)")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -56,6 +56,16 @@ TEST_CASE("t20013", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {
FindMessage(j, "tmain(int,char **)", "B", "b(int)"),
FindMessage(j, "B", "A", "a1(int)"),
FindMessage(j, "tmain(int,char **)", "B", "b(double)"),
FindMessage(j, "B", "A", "a2(double)"),
FindMessage(j, "tmain(int,char **)", "B", "b(const char *)"),
FindMessage(j, "B", "A", "a3(const char *)")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -54,6 +54,17 @@ TEST_CASE("t20014", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {
FindMessage(j, "tmain()", "B", "b1(int,int)"),
FindMessage(j, "B", "A", "a1(int,int)"),
FindMessage(j, "tmain()", "B", "b2(int,int)"),
FindMessage(j, "B", "A", "a2(int,int)"),
FindMessage(
j, "tmain()", "C<clanguml::t20014::B,int>", "c1(int,int)"),
FindMessage(j, "C<clanguml::t20014::B,int>", "B", "b1(int,int)")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -55,6 +55,11 @@ TEST_CASE("t20015", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {FindMessage(
j, "tmain()", "B", "setup_a(std::shared_ptr<detail::A> &)")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -50,6 +50,14 @@ TEST_CASE("t20016", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {
FindMessage(j, "tmain()", "B<long>", "b1(long)"),
FindMessage(j, "B<long>", "A", "a1(int)"),
FindMessage(j, "tmain()", "B<long>", "b2(long)"),
FindMessage(j, "B<long>", "A", "a2(const long &)")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -58,6 +58,20 @@ TEST_CASE("t20017", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {
FindMessage(j, File("t20017.cc"), File("include/t20017_a.h"),
"a3(int,int)"),
FindMessage(j, File("t20017.cc"), File("include/t20017_b.h"),
"b1(int,int)"),
FindMessage(j, File("t20017.cc"), File("include/t20017_a.h"),
"a2(int,int)"),
FindMessage(j, File("t20017.cc"), File("include/t20017_a.h"),
"a1(int,int)"),
FindMessage(j, File("t20017.cc"), File("include/t20017_b.h"),
"b2<int>(int,int)")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -62,6 +62,19 @@ TEST_CASE("t20018", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {
FindMessage(j, "tmain()",
"Answer<clanguml::t20018::Factorial<5>,120>", "print()"),
FindMessage(j, "Answer<clanguml::t20018::Factorial<5>,120>",
"Factorial<5>", "print(int)"),
FindMessage(j, "Factorial<5>", "Factorial<4>", "print(int)"),
FindMessage(j, "Factorial<4>", "Factorial<3>", "print(int)"),
FindMessage(j, "Factorial<3>", "Factorial<2>", "print(int)"),
FindMessage(j, "Factorial<2>", "Factorial<1>", "print(int)"),
FindMessage(j, "Factorial<1>", "Factorial<0>", "print(int)")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -50,6 +50,14 @@ TEST_CASE("t20019", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {
FindMessage(j, "tmain()", "Base<clanguml::t20019::D1>", "name()"),
FindMessage(j, "Base<clanguml::t20019::D1>", "D1", "impl()"),
FindMessage(j, "tmain()", "Base<clanguml::t20019::D2>", "name()"),
FindMessage(j, "Base<clanguml::t20019::D2>", "D2", "impl()")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -59,6 +59,20 @@ TEST_CASE("t20020", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {FindMessage(j, "tmain()", "A", "a1()"),
FindMessage(j, "tmain()", "A", "a2()"),
FindMessage(j, "tmain()", "C", "c3(int)"),
FindMessage(j, "tmain()", "B", "b1()"),
FindMessage(j, "tmain()", "A", "a3()"),
FindMessage(j, "tmain()", "B", "b2()"),
FindMessage(j, "tmain()", "A", "a4()"),
FindMessage(j, "tmain()", "B", "log()"),
FindMessage(j, "tmain()", "C", "c1()"),
FindMessage(j, "C", "C", "c2()"), FindMessage(j, "C", "C", "log()"),
FindMessage(j, "tmain()", "D<int>", "d1(int,int)")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -67,6 +67,23 @@ TEST_CASE("t20021", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {
FindMessage(j, "tmain()", "C", "c4()"),
FindMessage(j, "C", "C", "c5()"),
FindMessage(j, "tmain()", "A", "a3()"),
FindMessage(j, "tmain()", "A", "a2()"),
FindMessage(j, "tmain()", "C", "c1()"),
FindMessage(j, "tmain()", "C", "c2()"),
FindMessage(j, "tmain()", "A", "a1()"),
FindMessage(j, "tmain()", "C", "c3()"),
FindMessage(j, "tmain()", "B", "b2()"),
FindMessage(j, "tmain()", "C", "contents()")
// TODO: Repeated messge gets wrong index
// FindMessage(j, "tmain()", "B", "b2()")
};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -47,6 +47,11 @@ TEST_CASE("t20022", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {FindMessage(j, "tmain()", "A", "a()"),
FindMessage(j, "A", "B", "b()")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -50,6 +50,12 @@ TEST_CASE("t20023", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {FindMessage(j, "tmain()", "A", "a()"),
FindMessage(j, "A", "A", "a1()"), FindMessage(j, "A", "A", "a2()"),
FindMessage(j, "A", "A", "a3()"), FindMessage(j, "A", "A", "a4()")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -55,6 +55,13 @@ TEST_CASE("t20024", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {
FindMessage(j, "tmain()", "A", "select(enum_a)"),
FindMessage(j, "A", "A", "a0()"), FindMessage(j, "A", "A", "a1()"),
FindMessage(j, "A", "A", "a2()"), FindMessage(j, "A", "A", "a3()")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -50,6 +50,12 @@ TEST_CASE("t20025", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {FindMessage(j, "tmain()", "A", "a()"),
// FindMessage(j, "tmain()", "A", "a2()"),
FindMessage(j, "tmain()", "add(int,int)", "")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -46,6 +46,10 @@ TEST_CASE("t20026", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {FindMessage(j, "tmain()", "A", "a()")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -48,6 +48,10 @@ TEST_CASE("t20027", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {FindMessage(j, "tmain()", "A", "a()")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -50,6 +50,13 @@ TEST_CASE("t20028", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {FindMessage(j, "tmain()", "A", "a()"),
FindMessage(j, "tmain()", "A", "b()"),
FindMessage(j, "tmain()", "A", "c()"),
FindMessage(j, "tmain()", "A", "d()")};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -68,6 +68,20 @@ TEST_CASE("t20029", "[test-case][sequence]")
using namespace json;
std::vector<int> messages = {
FindMessage(j, "tmain()", "ConnectionPool", "connect()"),
FindMessage(j, "tmain()",
"Encoder<clanguml::t20029::Retrier<clanguml::t20029::ConnectionPool>>",
"send(std::string &&)")/*,
FindMessage(j,
"Encoder<clanguml::t20029::Retrier<clanguml::t20029::"
"ConnectionPool>>",
"encode_b64(std::string &&)", "encode_b64(std::string &&)"),
FindMessage(j, "Retrier<clanguml::t20029::ConnectionPool>",
"ConnectionPool", "send(const std::string &)")*/};
REQUIRE(std::is_sorted(messages.begin(), messages.end()));
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
}
}

View File

@@ -881,6 +881,13 @@ int find_message_nested(const nlohmann::json &j, const std::string &from,
return nested_res;
}
}
else if (m.contains("messages")) {
auto nested_res =
find_message_nested(m, from, to, msg, from_p, to_p, count);
if (nested_res >= 0)
return nested_res;
}
else {
if ((m["from"]["participant_id"] == from_p["id"]) &&
(m["to"]["participant_id"] == to_p["id"]) && (m["name"] == msg))
@@ -892,13 +899,13 @@ int find_message_nested(const nlohmann::json &j, const std::string &from,
return res;
}
} // namespace detail
int FindMessage(const nlohmann::json &j, const std::string &from,
int find_message_impl(const nlohmann::json &j, const std::string &from,
const std::string &to, const std::string &msg)
{
auto from_p = get_participant(j, expand_name(j, from));
auto to_p = get_participant(j, expand_name(j, to));
auto from_p = get_participant(j, from);
auto to_p = get_participant(j, to);
// TODO: support diagrams with multiple sequences...
const auto &sequence_0 = j["sequences"][0];
@@ -915,6 +922,30 @@ int FindMessage(const nlohmann::json &j, const std::string &from,
fmt::format("No such message {} {} {}", from, to, msg));
}
} // namespace detail
struct File {
explicit File(const std::string &f)
: file{f}
{
}
const std::string file;
};
int FindMessage(const nlohmann::json &j, const File &from, const File &to,
const std::string &msg)
{
return detail::find_message_impl(j, from.file, to.file, msg);
}
int FindMessage(const nlohmann::json &j, const std::string &from,
const std::string &to, const std::string &msg)
{
return detail::find_message_impl(
j, expand_name(j, from), expand_name(j, to), msg);
}
} // namespace json
}
}