Expand description
The standard serde/pbjson JSON encoding used by Rust stores google.protobuf.Any
fields as {"typeUrl": "...", "value": "<base64>"}. Go’s protojson library uses a
different encoding: {"@type": "...", "field1": val, ...} where the concrete message’s
fields are inlined. serde_json::from_str::<Plan> fails on Go-produced JSON because it
only understands the typeUrl/value form.
prost_reflect::DynamicMessage implements the full protobuf JSON mapping spec and
handles both forms, as long as the DescriptorPool contains the schema for every type
URL referenced in the JSON.
This module exposes build_descriptor_pool (to construct
the pool, optionally merging in extra descriptor blobs for extension types) and
parse_json (to parse a JSON string into a Plan using the pool).
§Example
use substrait_explain::json::{build_descriptor_pool, parse_json};
static MY_EXT: &[u8] = include_bytes!("my_extensions.bin");
let pool = build_descriptor_pool(&[MY_EXT]).unwrap();
// Works with both Go protojson and Rust pbjson encoding.
let plan = parse_json(json_str, &pool).unwrap();Functions§
- build_
descriptor_ pool - Build a
DescriptorPoolcovering the Substrait core schema plus any extra descriptor passed in. - parse_
json - Naive (
{"typeUrl": "...", "value": "<base64>"}): decoded viaserde_jsonandpbjson.This takes the protobuf fields of anAny(type_url,value) and serializes them like it would any other field. This is the ‘naive’ approach to JSON encoding protobufs; see https://github.com/influxdata/pbjson/issues/2Standard ({"@type": "...", "field": value, ...}): decoded viaprost-reflectAnyis a Well-Known Type in Protobuf, so in the standard, it has special handling: the protobuftype_urlshould become the JSON@typefield, and other fields should be inlined. See https://protobuf.dev/reference/protobuf/google.protobuf/#any.This requires the concrete type’s schema to be present inpool.