-
Notifications
You must be signed in to change notification settings - Fork 527
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
feat: Name
trait + Any
encoding support
#896
Conversation
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.
@tarcieri thanks for putting this together. Just curious if you've tried to use this with any other protobuf language impls to see if the type_url matching is supported? From what I remember the type url stuff always felt a bit fuzzy and felt like a google internal impl detail that was leaked. |
@LucioFranco I'm trying to interop with a Go reference implementation which makes pretty extensive use of That said you did make me take a second look and I did notice something a bit problematic in the type URL comparison. I'm not sure how other implementations handle the leading domain component of a type URL, i.e. if it mismatches, should the full type URL mismatch. Should type URLs with leading All that said, I deliberately made We might also consider an associated constant for the domain component, which could be blank. |
use alloc::{format, string::String}; | ||
|
||
/// Associate a type name with a [`Message`] type. | ||
pub trait Name: Message { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this just live in prost_types
, why does it need to live in the core crate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was hoping it could eventually be autogenerated by prost-build
, at least optionally. We're hand annotating them right now and it's getting quite cumbersome.
It seems like prost-build
currently only refers to types/traits in prost
. If it were optional and it could refer to types/traits in prost-types
, I'd be fine with the Name
trait living there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see your point, do we just want to go ahead and do the work to also add the prost-build parts? The next release will be breaking and I would be ok if we add something like that.
@tarcieri this looks good besides my one question, I am okay with merging mostly because a lot of this code can be kept outside the core crate. |
nice !!! |
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.
Build failure seems unrelated:
Edit: pushed 46e73e0 to address the test MSRV |
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
Regardless of what crate That would also make it possible to test Edit: went ahead and did this in cfe8a99 |
Also adds tests for `Any::{from_msg, to_msg}`.
Aside from the question of where the |
/// Type URL for this message, which by default is the full name with a | ||
/// leading slash, but may also include a leading domain name, e.g. | ||
/// `type.googleapis.com/google.profile.Person`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps this could include some of the documentation I added to the internal TypeUrl
type.
/// leading slash, but may also include a leading domain name, e.g. | ||
/// `type.googleapis.com/google.profile.Person`. | ||
fn type_url() -> String { | ||
format!("/{}", Self::full_name()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could potentially benefit from an easier way to customize the URL authority (i.e. hostname+port). It was a bit tricky to do this for the "well known" types:
|
||
/// Full name of this message type containing both the package name and | ||
/// type name, e.g. `google.protobuf.TypeName`. | ||
fn full_name() -> String { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these be &'static str
, is there a case where these are not statically defined with the generated proto?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If prost-build
filled them in they potentially could be all computed at build-time.
Otherwise it's not really possible to construct a &'static str
as a concatenation of Self::PACKAGE
+ '.'
+ Self::NAME
AFAIK.
@tarcieri sorry for dragging this a long, would you be interested in adding the prost-build part too then we can keep the trait in prost. I merged the msrv fix in another PR so would be good to back that out of this one. We could also merge this part now (once the msrv is backed out and this is rebased) and then we can add the prost-build stuff in a follow up. |
I can attempt to add the |
@tarcieri ok cool, let me know if I can help (feel free to ping on discord). I think I want to wait on this for the next (breaking) release which will basically happen after we get this merged. |
I'd like to get things merged and released today so I will go ahead and get this merged and figure out what else we need today and then we can add more stuff in point releases since they shouldn't be breaking changes. |
Sorry to disturb, is there any progress on the |
@tarcieri were you able to follow up on this? If not if anyone else is interested in picking this up? |
Not yet, and I'm on vacation. Would be great if someone else could pick it up. |
The `Name` trait added upstream in `prost` can be used to compute the type URL using `Name::type_url`: tokio-rs/prost#896 The new `Any::{from_msg, to_msg}` methods can be used to serialize `Message` types to/from messages. This commit switches from the `TypeUrl` trait to `Name` and relies more on upstream functionality in `prost`. Unfortunately it shipped with a bug in the default `Name::full_name` method, so a workaround is temporarily used until a fix ships: tokio-rs/prost#923
The `Name` trait added upstream in `prost` can be used to compute the type URL using `Name::type_url`: tokio-rs/prost#896 The new `Any::{from_msg, to_msg}` methods can be used to serialize `Message` types to/from messages. This commit switches from the `TypeUrl` trait to `Name` and relies more on upstream functionality in `prost`. Unfortunately it shipped with a bug in the default `Name::full_name` method, so a workaround is temporarily used until a fix ships: tokio-rs/prost#923
The `Name` trait added upstream in `prost` can be used to compute the type URL using `Name::type_url`: tokio-rs/prost#896 The new `Any::{from_msg, to_msg}` methods can be used to serialize `Message` types to/from messages. This commit switches from the `TypeUrl` trait to `Name` and relies more on upstream functionality in `prost`. Unfortunately it shipped with a bug in the default `Name::full_name` method, so a workaround is temporarily used until a fix ships: tokio-rs/prost#923
The `Name` trait added upstream in `prost` can be used to compute the type URL using `Name::type_url`: tokio-rs/prost#896 The new `Any::{from_msg, to_msg}` methods can be used to serialize `Message` types to/from messages. This commit switches from the `TypeUrl` trait to `Name` and relies more on upstream functionality in `prost`. Unfortunately it shipped with a bug in the default `Name::full_name` method, so a workaround is temporarily used until a fix ships: tokio-rs/prost#923
As discussed in #299 and #858, adds a
Name
trait which associates a type name and package constants with aMessage
type. It also providesfull_name
andtype_url
methods.The
type_url
method is used by newly added methods on theAny
type which can be used for decoding/encoding messages:Any::from_msg
: encodes a givenMessage
, returningAny
.Any::to_msg
: decodesAny::value
as the givenMessage
, first validating the message type has the expected type URL.