Skip to content

Commit

Permalink
Add option to output messages in JSON format (#288)
Browse files Browse the repository at this point in the history
Signed-off-by: Addisu Z. Taddese <[email protected]>
  • Loading branch information
azeey authored Mar 10, 2022
1 parent 663194c commit 8f60438
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 8 deletions.
21 changes: 19 additions & 2 deletions src/cmd/ign.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include <chrono>
#include <functional>
#include <google/protobuf/util/json_util.h>
#include <iostream>
#include <string>
#include <vector>
Expand Down Expand Up @@ -251,7 +252,7 @@ extern "C" void cmdServiceReq(const char *_service,

//////////////////////////////////////////////////
extern "C" void cmdTopicEcho(const char *_topic,
const double _duration, int _count)
const double _duration, int _count, MsgOutputFormat _outputFormat)
{
if (!_topic || std::string(_topic).empty())
{
Expand All @@ -266,7 +267,23 @@ extern "C" void cmdTopicEcho(const char *_topic,
std::function<void(const ProtoMsg&)> cb = [&](const ProtoMsg &_msg)
{
std::lock_guard<std::mutex> lock(mutex);
std::cout << _msg.DebugString() << std::endl;
switch (_outputFormat)
{
case MsgOutputFormat::kDefault:
case MsgOutputFormat::kDebugString:
std::cout << _msg.DebugString() << std::endl;
break;
case MsgOutputFormat::kJSON:
{
std::string jsonStr;
google::protobuf::util::MessageToJsonString(_msg, &jsonStr);
std::cout << jsonStr << std::endl;
}
break;
default:
std::cerr << "Invalid output format selected.\n";
return;
}
++count;
condition.notify_one();
};
Expand Down
21 changes: 18 additions & 3 deletions src/cmd/ign.hh
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,21 @@ extern "C" void cmdServiceReq(const char *_service,
const int _timeout,
const char *_reqData);

extern "C" {
/// \brief Enum used for specifing the message output format for functions
/// like cmdTopicEcho.
enum class MsgOutputFormat {
// Default. Currently, this is Protobuf's DebugString output format.
kDefault,

// Output format used in Protobuf's Message::DebugString.
kDebugString,

// JSON output.
kJSON
};
}

/// \brief External hook to execute 'ign topic -e' from the command line.
/// The _duration parameter overrides the _count parameter.
/// \param[in] _topic Topic name.
Expand All @@ -71,9 +86,9 @@ extern "C" void cmdServiceReq(const char *_service,
/// \param[in] _count Number of messages to echo and then stop. A value <= 0
/// indicates no limit. The _duration parameter overrides the _count
/// parameter.
extern "C" void cmdTopicEcho(const char *_topic,
const double _duration,
int _count);
/// \param[in] _outputFormat Message output format.
extern "C" void cmdTopicEcho(const char *_topic, const double _duration,
int _count, MsgOutputFormat _outputFormat);

/// \brief External hook to read the library version.
/// \return C-string representing the version. Ex.: 0.1.2
Expand Down
44 changes: 42 additions & 2 deletions src/cmd/ign_src_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*
*/

#include <future>
#include <string>
#include <iostream>
#include <sstream>
Expand Down Expand Up @@ -230,17 +231,56 @@ TEST(ignTest, cmdTopicEcho)
transport::Node node;

// Requesting a null topic should trigger an error message.
cmdTopicEcho(nullptr, 10.00, 0);
cmdTopicEcho(nullptr, 10.00, 0, MsgOutputFormat::kDefault);
EXPECT_EQ(stdErrBuffer.str(), "Invalid topic. Topic must not be empty.\n");
clearIOStreams(stdOutBuffer, stdErrBuffer);

cmdTopicEcho(kInvalidTopic.c_str(), 5.00, 0);
cmdTopicEcho(kInvalidTopic.c_str(), 5.00, 0, MsgOutputFormat::kDefault);
EXPECT_EQ(stdErrBuffer.str(), "Topic [/] is not valid.\n");
clearIOStreams(stdOutBuffer, stdErrBuffer);

restoreIO();
}

/////////////////////////////////////////////////
TEST(ignTest, cmdTopicEchoOutputFormats)
{
std::stringstream stdOutBuffer;
std::stringstream stdErrBuffer;
redirectIO(stdOutBuffer, stdErrBuffer);

transport::Node node;
ignition::msgs::Int32 msg;
msg.set_data(5);

clearIOStreams(stdOutBuffer, stdErrBuffer);

auto getSubscriberOutput = [&](MsgOutputFormat _outputFormat)
{
cmdTopicEcho(g_topic.c_str(), 3.00, 1, _outputFormat);
return stdOutBuffer.str();
};

auto defaultOutput = std::async(std::launch::async, getSubscriberOutput,
MsgOutputFormat::kDefault);

cmdTopicPub(g_topic.c_str(), g_intType.c_str(), msg.DebugString().c_str());
EXPECT_EQ("data: 5\n\n", defaultOutput.get());

clearIOStreams(stdOutBuffer, stdErrBuffer);

auto jsonOutput = std::async(std::launch::async, getSubscriberOutput,
MsgOutputFormat::kJSON);

msg.set_data(10);
cmdTopicPub(g_topic.c_str(), g_intType.c_str(), msg.DebugString().c_str());
EXPECT_EQ("{\"data\":10}\n", jsonOutput.get());

clearIOStreams(stdOutBuffer, stdErrBuffer);

restoreIO();
}

/////////////////////////////////////////////////
/// Main
int main(int argc, char **argv)
Expand Down
10 changes: 9 additions & 1 deletion src/cmd/topic_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ struct TopicOptions

/// \brief Number of messages to echo
int count{-1};

/// \brief Message output format
MsgOutputFormat msgOutputFormat {MsgOutputFormat::kDefault};
};

//////////////////////////////////////////////////
Expand All @@ -73,7 +76,8 @@ void runTopicCommand(const TopicOptions &_opt)
_opt.msgData.c_str());
break;
case TopicCommand::kTopicEcho:
cmdTopicEcho(_opt.topic.c_str(), _opt.duration, _opt.count);
cmdTopicEcho(_opt.topic.c_str(), _opt.duration, _opt.count,
_opt.msgOutputFormat);
break;
case TopicCommand::kNone:
default:
Expand Down Expand Up @@ -119,6 +123,10 @@ void addTopicFlags(CLI::App &_app)
opt->command = TopicCommand::kTopicEcho;
});

command->add_flag_callback("--json-output",
[opt]() { opt->msgOutputFormat = MsgOutputFormat::kJSON; },
"Output messages in JSON format");

command->add_option_function<std::string>("-p,--pub",
[opt](const std::string &_msgData){
opt->command = TopicCommand::kTopicPub;
Expand Down

0 comments on commit 8f60438

Please sign in to comment.