Expand description

Protofish is a decoder focused on decoding arbitrary protocol buffer messages with error recovery. Its primary use case is decoding gRPC mesages in proxide based on .proto-files supplied by the user at runtime.

use protofish::prelude::*;
use protofish::decode::UnknownValue;
use bytes::Bytes;

let context = Context::parse(&[r#"
  syntax = "proto3";
  package Proto;

  message Request { string kind = 1; }
  message Response { int32 distance = 1; }
  service Fish {
    rpc Swim( Request ) returns ( Response );
  }
"#]).unwrap();

let service = context.get_service("Proto.Fish").unwrap();
let rpc = service.rpc_by_name("Swim").unwrap();

let input = context.decode(rpc.input.message, b"\x0a\x05Perch");
assert_eq!(input.fields[0].number, 1);
assert_eq!(input.fields[0].value, Value::String(String::from("Perch")));

let output = context.decode(rpc.output.message, b"\x08\xa9\x46");
assert_eq!(output.fields[0].number, 1);
assert_eq!(output.fields[0].value, Value::Int32(9001));

let bytes = b"\x12\x07Unknown\x0a\x0fAtlantic ";
let request = context.get_message("Proto.Request").unwrap();
let value = request.decode(bytes, &context);
assert_eq!(value.fields[0].number, 2);
assert_eq!(
    value.fields[0].value,
    Value::Unknown(UnknownValue::VariableLength(Bytes::from_static(b"Unknown"))));
assert_eq!(
    value.fields[1].value,
    Value::Incomplete(2, Bytes::from_static(b"\x0fAtlantic ")));

let encoded = value.encode(&context);
assert_eq!(encoded, &bytes[..]);

Modules

Decoding context built from the proto-files.

Protocol buffer binary payload decoding.

Prelude that imports some of the commonly used types.