tokio-rs / prost

PROST! a Protocol Buffers implementation for the Rust Language
Apache License 2.0
3.78k stars 494 forks source link

Allow adding custom derive macros #431

Open cemoktra opened 3 years ago

cemoktra commented 3 years ago

Not sure if the proto options allow some per file or per package options. But there are some java specific options for example. And in my case it would be nice to add a derive macro to the generated struct in order to avoid having the struct again and writing conversion.

Something like:

message Foo {
  option rust_derive_macros = "SomeTrait";
  extensions 4 to max;
}
cemoktra commented 3 years ago

Also it may be interesting to not only add derive, but other macros. My use case for example would be to connect to a diesel schema:

#[derive(Queryable, Debug, Identifiable)]
#[table_name = "some_database_table"]
struct Foo {
...
}
ogoes commented 3 years ago

Hi, I'm new here.

I really like this feature!

I´ll try submit some code.

danburkert commented 3 years ago

Hi, please add more specific details about this feature request. Are prost_build::Config::type_attribute and prost_build::Config::field_attribute not sufficient for the usecase?

Langxxx commented 3 years ago

Also it may be interesting to not only add derive, but other macros. My use case for example would be to connect to a diesel schema:

#[derive(Queryable, Debug, Identifiable)]
#[table_name = "some_database_table"]
struct Foo {
...
}

I also need the same feature!

I use the diesel and i'm going to add some macros(like: Queryable, Insertable) to the generated structs.

Now I am manually copying the generated structure into the file to add macros, which feels stupid.

Any other ideas?

cemoktra commented 3 years ago

Hi, please add more specific details about this feature request. Are prost_build::Config::type_attribute and prost_build::Config::field_attribute not sufficient for the usecase?

Sorry i just came back to this. So type_attribute works actually but it feels kind of strange to put this information into the build.rs instead of the proto file while other language put these kind of information directly to the proto file. Anyway thank you

https://developers.google.com/protocol-buffers/docs/proto3#options

cemoktra commented 3 years ago

@danburkert i had some glimpse into the source code. Before i start working on a PR let me try to discuss this with you.

In order to run protoc -o i will need to create a .proto file that extends the MessageOptions. After that i will be able to handle the the option MessageOption struct from which i could add options to field_attributes just as the build config does. Correct?

So the main question for me would be, how to add a prost.proto file to the includes that defines prost specific options that can be used. Just add it to the bundled includes as they are preferred?

cs-clarence commented 1 year ago

Are there any updates on this? This approach seems less error prone than specifying them in the build.rs file

davo417 commented 10 months ago

Hello, I'm trying to implement this functionality for prost+influxdb with the following config:

fn main() -> Result<(), Box<dyn std::error::Error>> {
    tonic_build::configure()
        .type_attribute("sensor.SensorReading", "#[derive(InfluxDbWriteable)]")
        .field_attribute("sensor.SensorReading.id", "#[influxdb(tag)]")
        .compile(&["./protos/sensor.proto"], &["./protos/"])?;
    Ok(())
}

But when compiling I encounter the following error:

error: cannot find derive macro `InfluxDbWriteable` in this scope
 --> /home/david/projects/rustwp/ecs/target/debug/build/ecs-f5fecc71596c1f28/out/sensor.rs:4:10
  |
4 | #[derive(InfluxDbWriteable)]
  |          ^^^^^^^^^^^^^^^^^
  |
help: consider importing one of these items
 --> src/server.rs:13:5
  |
13+     use crate::InfluxDbWriteable;
 --> src/server.rs:13:5
  |
13+     use influxdb::InfluxDbWriteable;
  |

error: cannot find attribute `influxdb` in this scope
  --> /home/david/projects/rustwp/ecs/target/debug/build/ecs-f5fecc71596c1f28/out/sensor.rs:11:7
   |
11 |     #[influxdb(tag)]
   |       ^^^^^^^^
   |
   = note: `influxdb` is in scope, but it is a crate, not an attribute

It looks to me that somehow I have to provide a use:: directive to prost_build, but I can't find how in the docs.

vijaypm commented 8 months ago

@davo417 Not sure if you figured out the solution but just in case you haven't yet.... I ran into a similar issue with trying to derive serde:Serializable. The solution that worked for me was making sure that the dependencies in Cargo.toml included serde = { version = "1.0.193", features = ["derive"] } and specifying the full path when calling type_attribute like so .type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]") Hope this helps.

caspermeijn commented 1 week ago

The requested functionality first needs prost to support message options. There is another issue open for that: https://github.com/tokio-rs/prost/issues/425