Skip to content

Commit

Permalink
Merge pull request #9 from oberbichler/feature/from-json
Browse files Browse the repository at this point in the history
Add `from_json`
  • Loading branch information
oberbichler authored Jul 10, 2023
2 parents 83eea1b + 09e230c commit 9bb908e
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 239 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Protosaurus

Parse ProtoBuffer messages at runtime.
Parse and create ProtoBuffer messages at runtime.

[![Pip Action Status][actions-pip-badge]][actions-pip-link]
[![Wheel Action Status][actions-wheels-badge]][actions-wheels-link]
Expand Down Expand Up @@ -58,5 +58,12 @@ data = ctx.to_json('Animal', b64decode('CglJZ3Vhbm9kb24QARkAAAAAAAAkQA=='))
data = ctx.to_json('Animal', bytes.fromhex('0a09496775616e6f646f6e1001190000000000002440'))

print(data)
# >>> {"name":"Iguanodon","diet":"herbivorous","length":10}
# >>> '{"name":"Iguanodon","diet":"herbivorous","length":10}'


# convert json to protobuf
data = ctx.from_json('Animal', json.dumps({"name":"Iguanodon","diet":"herbivorous","length":10}))

print(data)
# >>> b'\n\tIguanodon\x10\x01\x19\x00\x00\x00\x00\x00\x00$@'
```
179 changes: 0 additions & 179 deletions include/protosaurus/detail/json.h

This file was deleted.

47 changes: 41 additions & 6 deletions include/protosaurus/protosaurus.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#pragma once

#include "detail/json.h"

#include <protosaurus/protosaurus.h>

#include <nanobind/nanobind.h>
Expand All @@ -13,6 +11,7 @@
#include <google/protobuf/io/tokenizer.h> // Tokenizer
#include <google/protobuf/io/zero_copy_stream_impl.h> // ArrayInputStream
#include <google/protobuf/message.h> // Message
#include <google/protobuf/util/json_util.h> // MessageToJsonString,

#include <ios> // boolalpha
#include <iosfwd> // ostream
Expand Down Expand Up @@ -92,13 +91,49 @@ class Context {

// write json

std::stringstream out;
std::string out;

absl::Status status = util::MessageToJsonString(*message, &out);

return out;
}

nb::bytes from_json(std::string message_type, std::string data) {
// get descriptor

const Descriptor* descriptor = m_pool.FindMessageTypeByName(message_type);

if (descriptor == nullptr) {
throw std::runtime_error("Could not find descriptor for message type \"" + message_type + "\"");
}

// generate prototype message

DynamicMessageFactory factory;

const Message* prototype = factory.GetPrototype(descriptor);

if (prototype == nullptr) {
throw std::runtime_error("Could not create prototype");
}

// parse data

std::unique_ptr<Message> message(prototype->New());

if (message == nullptr) {
throw std::runtime_error("Could not create empty message from prototype");
}

// write json

std::string out;

out << std::boolalpha;
absl::Status status = util::JsonStringToMessage(data, message.get());

detail::push_msg(out, *message);
message->SerializeToString(&out);

return out.str();
return nb::bytes(out.c_str(), out.size());
}
};

Expand Down
3 changes: 2 additions & 1 deletion src/protosaurus_ext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ NB_MODULE(protosaurus_ext, m) {
nb::class_<Context>(m, "Context")
.def(nb::init<>())
.def("add_proto", &Context::add_proto, "name"_a, "content"_a)
.def("to_json", &Context::to_json, "message_type"_a, "data"_a);
.def("to_json", &Context::to_json, "message_type"_a, "data"_a)
.def("from_json", &Context::from_json, "message_type"_a, "json"_a);
}
Loading

0 comments on commit 9bb908e

Please sign in to comment.