Skip to content

Conversation

maxpowa
Copy link

@maxpowa maxpowa commented Sep 22, 2025

This change will allow Prost users to skip a field during serialization and deserialization. It also provides an optional default attribute for these fields, in the event the underlying object does not implement the Default trait.

My motivation for this is some reverse engineering effort, in which the existing datastructures are serialized in both protobuf and xml formats. I can use quick_xml/serde and ignore protobuf-only fields, but I can't ignore xml-only fields using prost, which results in duplicate data structures and more boilerplate to convert between the two types.

Usage:

#[derive(::prost::Message)]
struct Test {
    #[prost(int32, tag = "1")]
    a: i32,
    #[prost(skip)]
    b: i32,
    #[prost(skip, default = "create_foo")]
    c: Foo,
}

#[derive(Debug)]
struct Foo(i32);

pub fn create_foo() -> Foo {
    Foo(12)
}

Related: #174


This appears to work locally, but I can't get the full test suite to run (even with clean main branch). I'd like to add some integration tests for this, but it seems the only tests for derive currently are the existing Protobuf known-types (where this wouldn't really make sense), and a few negative test cases in the derive package.

@maxpowa maxpowa changed the title Skip fields Skip field attribute Sep 22, 2025
@maxpowa maxpowa changed the title Skip field attribute Skip field derive macro attribute Sep 22, 2025
@maxpowa maxpowa changed the title Skip field derive macro attribute feat: skip field derive macro attribute Sep 22, 2025
@maxpowa maxpowa force-pushed the skip-fields branch 2 times, most recently from 9f99c58 to 9412bfb Compare September 22, 2025 04:27
@maxpowa maxpowa changed the title feat: skip field derive macro attribute feat(prost-derive): skip field attribute Sep 22, 2025
Copy link
Contributor

@caspermeijn caspermeijn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the skip option. I see how this could be useful when using prost-derive.

I am not sure how I feel about the default attribute. Why doesn't each of the skipped types implement default?

I miss tests. You could take some inspiration from tests/src/custom_debug.rs or prost-derive/src/lib.rs.

I miss documentation. The documentation of derive attributes is not great, but this new attr should at least be mentioned in README.md

@maxpowa
Copy link
Author

maxpowa commented Oct 6, 2025

I am not sure how I feel about the default attribute. Why doesn't each of the skipped types implement default?

The default attribute exists because the skipped type may be external to the implementation, and might not implement default upstream. The attribute is optional, and will rely on the type implementing Default if not defined.

This will make prost ignore the field during serialization and deserialization. The field must implement the "Default" trait for this to work properly.
Prevents the skipped field from needing to implement the `Default` trait.

Usage:

```rs
struct Test {
    #[prost(int32, tag = "1")]
    a: i32,
    #[prost(skip)]
    c: i32,
    #[prost(skip, default = "create_foo")]
    d: Foo,
}

struct Foo(i32);

pub fn create_foo() -> Foo {
    Foo(12)
}
```
The `default` keyword was being picked up by the skip handler for fields which weren't tagged with the `skip` attribute.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants