Crates.io | prost-convert-derive |
lib.rs | prost-convert-derive |
version | 0.3.0 |
source | src |
created_at | 2024-08-19 09:39:06.827018 |
updated_at | 2024-08-19 09:39:06.827018 |
description | Proc macro used in prost-convert. |
homepage | |
repository | https://github.com/silicom-hub/prost-convert |
max_upload_size | |
id | 1343662 |
size | 49,744 |
This crate provides a derive macro for TryFromProto
and FromNative
traits.
Prost wrap user defined messages into optional, as stated by the proto3 specs.
One idea of the macro is that if the proto struct has a field which is optional and the native ones no, provide a conversion function that will try to do the conversion.
Sadly, we can't know in the derive macro if the proto struct field is optional. We only got the struct path, we can't simply go and parse it.
So there if we use From
and TryFrom
, there is no way to customize the behavior if the proto struct field is optional, because we don't know if it does.
One solution will be to provide
#[required]
attribute on the field on the native struct but that's verbose and add some boilerplate.
Besides TryFrom<Option<T>> for T
is not implemented and not implementable because of the orphan rule.
For instance, this won't work :
let option = Some(String::from("foo"));
let string: String = o.try_into()?;
So we make our own trait to be able to define what to do when converting from an Opion<T>
into a T
.
What we really need is to convert to the wrapper to send it over the network. And be created from the wrapper after receiving it through the network. So we must specify the wrapper path. But from the wrapper path we can't deduce the wrapped path and vice versa. If the native is an enum can we assume the src given is a struct which has only one field which is an enum? -> No Currently we need to impl ProstConvert for each nested struct. So we can have enum which are not inside a wrapper struct. If the wrapper makes just a recursive call, maybe it’s possible not to provide the wrapped?
Syntax for enum:
#[derive(ProstConvert)]
#[prost_convert(src = "proto::Foo", wrapper = "proto::FooWrapper")]
enum Foo {
Foo1,
Foo2,
}
This will generate 2 implementations of [TryFromProto
] :
The "src" attribute will do the same as it does for the struct, it will generate:
impl TryFromProto<proto::Foo> for Foo
impl FromNative<Foo> for proto::Foo
But the "wrapper" attribute will also generate 2 more convertion function, with the wrapper struct:
impl TryFromProto<proto::FooWrapper> for Foo
impl FromNative<Foo> for proto::FooWrapper
If you use the wrapper keyword, no need to derive ProstConvert
for the wrapper itself. In other words, we don't need
impl TryFromProto<proto::FooWrapper> for FooWrapper
impl FromNative<FooWrapper> for proto::FooWrapper
For now:
wrapper can only be used on enum (easy to make it for struct but is there a use case?)
wrapper assumes that the wrapper is a struct of one filed containing one enum.
Currently this macro impl both TryFromProto
and FromNative
, but maybe sometimes we only want one of those.
Just use darling for parsing macro argument (check if it integrates well with syn::Error
).
Compile error when a field doesn't impl prost derive should be on the field and not on the struct (like when missing Debug, Clone, etc..)
compile error when [prost_convert(src = "..")]
appear at the top of struct comment => shouldn't be the case.
Does we use all the variants of the error?
Confirm that Style::Tuple
and Style::Tuple
can't be created from protobuf.
Provide custom impl if wanted? For instance, to create std::net::IpAddress
from std::string
.
Handle new type struct Id(Uuid)
.
Handle tuple struct Foo(i32, i32)
Add UT for this pub struct Message {}
Handle "struct" enum variant or mark it in the doc. Beside if we don't support it, we can add a compile error on the macro.
Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.