Completely overhaul protobuf message design.

The new format is now way easies to work with.
This commit is contained in:
Christoph Heiss 2018-03-04 22:25:35 +01:00
parent f7683abf0b
commit 7955e22780
3 changed files with 76 additions and 74 deletions

View file

@ -12,24 +12,16 @@ package rslp;
message Command {
enum Type {
Nil = 0;
String = 1;
Error = 2;
Integer = 3;
Array = 4;
}
message Data {
oneof data {
string str = 1;
sint64 int = 2;
Command subdata = 3;
string err = 2;
sint64 int = 3;
Command array = 4;
}
}
Type type = 1;
repeated Data data = 2;
repeated Data data = 1;
}

View file

@ -49,41 +49,42 @@ static Options parse_commandline(int argc, char** argv)
}
std::ostream& operator<<(std::ostream& ostream, const rslp::Command& command)
{
switch (command.type()) {
case rslp::Command::Nil:
using Type = rslp::Command_Data::DataCase;
for (int i{}; i < command.data_size(); i++) {
auto data{command.data(i)};
if (command.data_size() > 1) {
ostream << i+1 << ") ";
}
switch (data.data_case()) {
case Type::kErr:
ostream << "(error) \"" << data.err() << '"';
break;
case Type::kStr:
ostream << '"' << data.str() << '"';
break;
case Type::kInt:
ostream << data.int_();
break;
case Type::kArray:
ostream << data.array();
break;
default:
ostream << "(nil)";
break;
case rslp::Command::Error:
ostream << "(error) ";
[[fallthrough]];
case rslp::Command::String:
ostream << '"' << command.data(0).str() << '"';
break;
case rslp::Command::Integer:
ostream << command.data(0).int_();
break;
case rslp::Command::Array: {
auto data{command.data()};
for (int i{}; i < command.data_size(); i++) {
ostream << i+1 << ") " << command.data(i).subdata();
if (i < command.data_size()-1) {
ostream << '\n';
}
}
break;
}
default: /* To silence to compiler */
break;
if (command.data_size() > 1 && i < command.data_size()-1) {
ostream << '\n';
}
}
return ostream;
@ -124,11 +125,9 @@ public:
rslp::Command send_command(const std::vector<std::string>& arguments)
{
rslp::Command command;
command.set_type(rslp::Command::Array);
for (const std::string& arg: arguments) {
auto* data{command.add_data()};
data->set_str(arg);
command.add_data()->set_str(arg);
}
send_data(command);
@ -207,7 +206,8 @@ int main(int argc, char* argv[])
command.push_back(line);
}
std::cout << client.send_command(command) << std::endl;
rslp::Command result{client.send_command(command)};
std::cout << result << std::endl;
}

View file

@ -187,10 +187,8 @@ public:
logger_->debug("Received '{}' on {}", debug_string, remote_address_);
std::vector<std::string> resply_command;
const auto arguments{command.mutable_data()};
for (int i{}; i < arguments->size(); i++) {
resply_command.push_back(arguments->Get(i).str());
for (const auto& arg: command.data()) {
resply_command.push_back(arg.str());
}
resply::Result result{client_.command(resply_command)};
@ -236,49 +234,61 @@ private:
asio::write(socket_, asio::buffer(output.data(), output.size()));
}
static void resply_result_to_rslp(rslp::Command& command, const resply::Result& result) {
static void resply_result_to_rslp(rslp::Command& command, const resply::Result& result)
{
using Type = resply::Result::Type;
switch (result.type) {
case Type::String: {
command.set_type(rslp::Command::String);
auto data{command.add_data()};
data->set_str(result.string);
case Type::ProtocolError:
case Type::IOError:
command.add_data()->set_err(result.string);
break;
}
case Type::Integer: {
command.set_type(rslp::Command::Integer);
auto data{command.add_data()};
data->set_int_(result.integer);
case Type::String:
command.add_data()->set_str(result.string);
break;
}
case Type::Array: {
command.set_type(rslp::Command::Array);
case Type::Integer:
command.add_data()->set_int_(result.integer);
break;
case Type::Array:
for (const auto& element: result.array) {
auto data{command.add_data()};
resply_result_to_rslp(*data->mutable_subdata(), element);
resply_result_to_rslp_data(command.add_data(), element);
}
break;
}
case Type::ProtocolError:
case Type::IOError: {
command.set_type(rslp::Command::Error);
auto data{command.add_data()};
data->set_str(result.string);
break;
}
case Type::Nil:
command.set_type(rslp::Command::Nil);
break;
}
}
static void resply_result_to_rslp_data(rslp::Command_Data* data, const resply::Result& result)
{
using Type = resply::Result::Type;
switch (result.type) {
case Type::String:
data->set_str(result.string);
break;
case Type::Integer:
data->set_int_(result.integer);
break;
case Type::Array:
for (const auto& element: result.array) {
resply_result_to_rslp(*data->mutable_array(), element);
}
break;
default:
/* Cannot happen */
break;
}
}
resply::Client client_;
asio::ip::tcp::socket socket_;
std::shared_ptr<spdlog::logger> logger_;