-
Notifications
You must be signed in to change notification settings - Fork 518
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Serializing a Message to Any #299
Comments
+1, I need to deserialize an |
Similar to #277. |
Subscribed... I know how to go from a type to Any, but not the other way around. |
The tools for de-serializing an Any type is already there, you can match on the type URL, and decode the value field using Message::decode. With a little bit of macro magic you don't have to write a lot of code, I have made an example repo. IMO this is simpler and can easily be adapted to your own needs. |
If there is a mechanism for Message to return type_url, it can support generics. use prost::Message;
use prost_types::Any;
fn to_any<T>(message: &T) -> Any where T: Message {
Any {
type_url: T::type_url().to_string(),
value: message.encode_to_vec(),
}
}
fn from_any<T>(message: &Any) -> Result<T, DecodeError> where T: Message + Default {
if &message.type_url == T::type_url() {
T::decode(message.value.as_slice())
} else {
Err(DecodeError::new("Invalid type_url"))
}
} |
Adding a |
@vbkaisetsu is there a type_url for |
@nyanchor I previously created #535 to support seamless seriarization, but it needs further discussion. |
Yeah, I think supporting this is a good idea. Will need to dig in a bit more to understand how other languages support this feature. |
When trying to define an `osmosis-proto` crate (#239), we ran into the problem that it needed to import `cosmrs` to be able to impl the `MsgProto` trait. We couldn't follow the same pattern as `cosmrs` defining the type URLs for `cosmos-sdk-proto`, which it could only do because it defined the `MsgProto` trait as well. Knowledge of the type URLs is necessary to convert to/from `Any`, which Cosmos SDK uses all over the place. So far there isn't a good upstream solution to this problem in `prost` or AFAICT in `tendermint-proto` either. There's an upstream tracking issue for `prost` here: tokio-rs/prost#299 The ideal solution to this problem seems to be adding a `TYPE_URL` to `prost::Message`, and automatically populating them with `prost-build`. Failing that, this commit introduces a `TypeUrl` trait with an associated `TYPE_URL` const (previously provided by the `MsgProto` trait). The `from_any` and `to_any` methods have been moved to `MessageExt`.
When trying to define an `osmosis-proto` crate (#239), we ran into the problem that it needed to import `cosmrs` to be able to impl the `MsgProto` trait. We couldn't follow the same pattern as `cosmrs` defining the type URLs for `cosmos-sdk-proto`, which it could only do because it defined the `MsgProto` trait as well. Knowledge of the type URLs is necessary to convert to/from `Any`, which Cosmos SDK uses all over the place. So far there isn't a good upstream solution to this problem in `prost` or AFAICT in `tendermint-proto` either. There's an upstream tracking issue for `prost` here: tokio-rs/prost#299 The ideal solution to this problem seems to be adding a `TYPE_URL` to `prost::Message`, and automatically populating them with `prost-build`. Failing that, this commit introduces a `TypeUrl` trait with an associated `TYPE_URL` const (previously provided by the `MsgProto` trait). The `from_any` and `to_any` methods have been moved to `MessageExt`.
@LucioFranco the simplest way to support it is adding an associated Then |
When trying to define an `osmosis-proto` crate (#239), we ran into the problem that it needed to import `cosmrs` to be able to impl the `MsgProto` trait. We couldn't follow the same pattern as `cosmrs` defining the type URLs for `cosmos-sdk-proto`, which it could only do because it defined the `MsgProto` trait as well. Knowledge of the type URLs is necessary to convert to/from `Any`, which Cosmos SDK uses all over the place. So far there isn't a good upstream solution to this problem in `prost` or AFAICT in `tendermint-proto` either. There's an upstream tracking issue for `prost` here: tokio-rs/prost#299 The ideal solution to this problem seems to be adding a `TYPE_URL` to `prost::Message`, and automatically populating them with `prost-build`. Failing that, this commit introduces a `TypeUrl` trait with an associated `TYPE_URL` const (previously provided by the `MsgProto` trait). The `from_any` and `to_any` methods have been moved to `MessageExt`.
@tarcieri yes, though I don't remember (or couldn't find but didn't look super hard) if there was actually a concrete way to generate that url that isn't google specific etc. |
To my knowledge the type URLs take the form:
e.g.
|
Bumping this one up as it's definitely something that will make my life easier. |
Do we have any latest process? |
One way to get started would be to add a trait with a carrier for the type URL: pub trait TypeUrl: Message {
const TYPE_URL: &'static str;
} This would avoid the need to immediately populate it for every At least initially, the Edit: opened a PR with this idea: #858 |
As discussed in tokio-rs#299, adds a `TypeUrl` trait which associates a type URL constant with a `Message` type. This enables adding methods to `Any` for decoding/encoding messages: - `Any::from_message`: encodes a given `Message`, returning `Any`. - `Any::to_message`: decodes `Any::value` as the given `Message`, first validating the message type has the expected type URL.
As discussed in tokio-rs#299, adds a `TypeUrl` trait which associates a type URL constant with a `Message` type. This enables adding methods to `Any` for decoding/encoding messages: - `Any::from_message`: encodes a given `Message`, returning `Any`. - `Any::to_message`: decodes `Any::value` as the given `Message`, first validating the message type has the expected type URL.
As discussed in tokio-rs#299, adds a `TypeUrl` trait which associates a type URL constant with a `Message` type. This enables adding methods to `Any` for decoding/encoding messages: - `Any::from_message`: encodes a given `Message`, returning `Any`. - `Any::to_message`: decodes `Any::value` as the given `Message`, first validating the message type has the expected type URL.
As discussed in tokio-rs#299, adds a `TypeUrl` trait which associates a type URL constant with a `Message` type. This enables adding methods to `Any` for decoding/encoding messages: - `Any::from_message`: encodes a given `Message`, returning `Any`. - `Any::to_message`: decodes `Any::value` as the given `Message`, first validating the message type has the expected type URL.
As discussed in tokio-rs#299, adds a `TypeUrl` trait which associates a type URL constant with a `Message` type. This enables adding methods to `Any` for decoding/encoding messages: - `Any::from_message`: encodes a given `Message`, returning `Any`. - `Any::to_message`: decodes `Any::value` as the given `Message`, first validating the message type has the expected type URL.
As discussed in tokio-rs#299 and tokio-rs#858, adds a `Name` trait which associates a type name and package constants with a `Message` type. It also provides `full_name` and `type_url` methods. The `type_url` method is used by newly added methods on the `Any` type which can be used for decoding/encoding messages: - `Any::from_msg`: encodes a given `Message`, returning `Any`. - `Any::to_msg`: decodes `Any::value` as the given `Message`, first validating the message type has the expected type URL.
I opened #896 as my latest attempt to implement this feature |
* feat: `Name` trait + `Any` encoding support As discussed in #299 and #858, adds a `Name` trait which associates a type name and package constants with a `Message` type. It also provides `full_name` and `type_url` methods. The `type_url` method is used by newly added methods on the `Any` type which can be used for decoding/encoding messages: - `Any::from_msg`: encodes a given `Message`, returning `Any`. - `Any::to_msg`: decodes `Any::value` as the given `Message`, first validating the message type has the expected type URL. * Add private `TypeUrl` type Implements the basic rules for parsing type URLs as documented in: https://github.com/protocolbuffers/protobuf/blob/a281c13/src/google/protobuf/any.proto#L129C2-L156C50 Notably this extracts the final path segment of the URL which contains the full name of the type, and uses that for type comparisons. * CI: bump test toolchain to 1.64 This is the MSRV of `petgraph` now: error: package `petgraph v0.6.4` cannot be built because it requires rustc 1.64 or newer, while the currently active rustc version is 1.63.0 * Add `Name` impls for well-known protobuf types Also adds tests for `Any::{from_msg, to_msg}`. * Fix no_std --------- Co-authored-by: Lucio Franco <luciofranco14@gmail.com>
@tarcieri would you mind indicating why I can implement prost-build; however, a better approach would remove those unnecessary traits
|
Please see the discussion here: #858 (comment)
There is currently no In the future when there is |
so it’s a problem with the design + impl not any technical decision / desire ? If that’s the case — prost::Message::type_url can trivially be added to prost-build |
It’s something that could potentially be merged into |
Merging |
Yeah, the |
I'm unable to find any docs on how to create an Any from a Message. Do I need to serialize the message myself and set the typeURL?
The text was updated successfully, but these errors were encountered: