Skip to content

Conversation

@v0idpwn
Copy link
Collaborator

@v0idpwn v0idpwn commented Apr 13, 2025

This PR is on-top of #398.

Adds a unified presence tracking module. Makes the different encoders use it when deciding whether to skip a field or not.

Adds a public API for checking field presence on Protobuf.Presence.field_presence/2. This is similar to the feature present on the official protobuf libraries, but with a different API.

In Ruby, for example, fields that have explicit presence tracking generate a has_{field_name}? method:

message = MyMessage.new()
message.has_foo? #=> false
message.foo = 0
message.has_foo? # => true

If another field, say bar, doesn't have explicit presence tracking (e.g.: it is a non-optional, non-one_of proto3), it simply doesn't generate the has_bar? method, so you can't "presence-check" these fields.

My proposed API is a bit different, and allows presence-checking :bar, but sometimes giving
a :maybe as a response:

message = %Message{}
Protobuf.Presence.field_presence(message, :foo)
#=> :not_present
Protobuf.Presence.field_presence(%Message{foo: 0}, :foo)
#=> :present

Protobuf.Presence.field_presence(%Message{}, :bar)
#=> :maybe
Protobuf.Presence.field_presence(%Message{bar: 0}, :bar)
#=> :maybe
Protobuf.Presence.field_presence(%Message{bar: 1}, :bar)
#=> :present

Motivation

I think it makes sense to centralize presence checking for a few reasons:

  1. Presence rules become even more complex with protobuf editions and I'd like to add support for them soon, so this refactoring seems opportune
  2. Existing logic is a bit ad-hoc and duplicated. Seemed like a good opportunity to improve the code I noticed when adding Protobuf.Text.
  3. Official protobuf libraries provide APIs for presence checking and I don't see why this one shouldn't

@v0idpwn v0idpwn force-pushed the feat/field-presence branch from 0e75db0 to e0f7de6 Compare April 13, 2025 02:58
@v0idpwn v0idpwn marked this pull request as draft April 13, 2025 12:35
Unifies presence tracking between encoders. Provides a public API for checking field presence
@v0idpwn v0idpwn force-pushed the feat/field-presence branch from 6314c1b to 79745cc Compare April 13, 2025 12:51
@v0idpwn v0idpwn marked this pull request as ready for review April 13, 2025 13:24
@v0idpwn v0idpwn requested a review from whatyouhide April 14, 2025 20:07
@v0idpwn
Copy link
Collaborator Author

v0idpwn commented Apr 15, 2025

I will merge this to #398, and continue working from there. If you have any feedback, you can give it either here or there :)

@v0idpwn v0idpwn merged commit fec5bf1 into feat/text-encoding Apr 15, 2025
4 checks passed
@v0idpwn v0idpwn deleted the feat/field-presence branch April 15, 2025 21:25
@whatyouhide
Copy link
Collaborator

I love this but I would expose the function on the Profobuf module and make Protobuf.Presence private, thoughts?

@v0idpwn
Copy link
Collaborator Author

v0idpwn commented Apr 19, 2025

Great idea, will do!

v0idpwn added a commit that referenced this pull request Apr 30, 2025
* Create Protobuf.Presence module

Unifies presence tracking between encoders. Provides a public API for checking field presence

* Add test for messages, fix proto3

* Improve docs
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.

3 participants