Skip to content
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

Allow ignoring fields #174

Open
mashedcode opened this issue Apr 4, 2019 · 6 comments
Open

Allow ignoring fields #174

mashedcode opened this issue Apr 4, 2019 · 6 comments

Comments

@mashedcode
Copy link

If one has a structure which carries data and temporary state. One might want to encode only the data and ignore the rest.

It seems to me that the simplest way to implement this would be to simply ignore fields which are not annotated.
As part of this I'd also stop generating impl Default since a user may very well want to implement it himself to initialize the ignored fields correctly.
For generated code a simple #[derive(Default should do the trick IIUC.
Either way this would be a breaking change.

Suggestions?

I'd be happy to implement.

@fanhaining
Copy link

I really need this

@DontBreakAlex
Copy link

I also found myself needing this. I have a existing very large struct and I don't want to clone it only to drop a field...

@caspermeijn
Copy link
Collaborator

I don't understand what you are trying to do. Can you provide an reproducible example?

@commonsensesoftware
Copy link

I do not think this applies to types that use *.proto files because they simply would not be code-generated. I have a use case where I want to model a message and ProtoBuf just happens to be the serialization format I want to use. I don't what to have to create DTOs or other intermediate structs just to drop the unwanted field.

Example:

#[derive(Message)]
struct Event {
    #[prost(uint32)]
    id: u32,

    #[prost(skip)]
    version: u32,

   /// ... other fields
}

I have no interest in storing version because it's irrelevant to the encoded message. I need and store that information outside of the struct; however, it's a lot of extra work and ceremony to wrap that behavior over another struct or provide a conversion struct. Similarly, having version: Option<u32> and setting it to None isn't much help. It's still a field in ProtoBuf's eyes.

It doesn't really matter what it's called. serde uses #[serde(skip)] so this would be congruent, but #[prost(ignore)] is just as meaningful IMHO. This problem can be exacerbated by a field that is much larger in size. There should be some way to ignore such a field. Since every field used this way requires an annotation, I'm also onboard with simply ignoring any field that doesn't have an annotation.

@caspermeijn
Copy link
Collaborator

What do you expect the value to be when such a struct is deserialized?

Having a skip attribute makes sense to me. It needs someone to actually implement this.

@commonsensesoftware
Copy link

I'm open to possibilities, but I'd imagine rules similar to serde.

  1. The field must support Default, which works for any primitive and recursively, in particular, for Option
  2. Support wiring up a function which allow providing a default value, which cannot otherwise be idiomatically provided (ex: #[prost(skip, default_value="custom_init_fn")])

Revising the setup, it might be something more contrived like:

fn get_answer() -> u32 {
    42
}

#[derive(Message)]
struct Event {
    #[prost(uint32)]
    id: u32,

    #[prost(skip)]
    version: u32,

    #[prost(skip, default_value = "get_answer")]
    answer_to_the_universe: u32,

    #[prost(skip)]
    answer: Option<String>,

   /// ... other fields
}

The implementation macro would expand struct initialization to something like:

let mut message = Event {
    id: Default::default(),
    version: Default::default(),
    answer_to_the_universe: get_answer(),
    answer: Default::default()
}

At this point, things can resume down the Message::merge_field path, which would ignore fields that are skipped. I think that's already covered because there won't be any tags for those fields in the message.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants