refactor(protocols): use serde_with::skip_serializing_none to reduce boilerplate - #342
Conversation
…boilerplate Replace repetitive per-field `#[serde(skip_serializing_if = "Option::is_none")]` annotations with the struct-level `#[serde_with::skip_serializing_none]` macro across the protocols crate. This removes ~290 boilerplate annotations. Only applied to types where ALL Option<T> fields already had the annotation, ensuring zero serialization behavior changes.
📝 WalkthroughWalkthroughThis PR adds the Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
Summary of ChangesHello @CatherineSue, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly refactors the Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request is an excellent refactoring that significantly reduces boilerplate in the protocols crate. Using #[serde_with::skip_serializing_none] at the struct/enum level instead of per-field #[serde(skip_serializing_if = "Option::is_none")] annotations makes the code much cleaner and more maintainable.
I'm impressed by the thoroughness of this change. The detailed PR description, which includes a list of types that were intentionally skipped to avoid changing serialization behavior, shows great attention to detail. I've spot-checked several of these cases and can confirm the reasoning is sound.
Overall, this is a high-quality contribution that improves the codebase. Great work!
…boilerplate (#342) Signed-off-by: ppraneth <pranethparuchuri@gmail.com>
Description
Problem
The protocols crate has ~400 repetitive
#[serde(skip_serializing_if = "Option::is_none")]field annotations scattered across 12 files, adding visual noise and maintenance burden.Solution
Add the
serde_withcrate and use#[serde_with::skip_serializing_none]at the struct/enum level, which automatically appliesskip_serializing_if = "Option::is_none"to allOption<T>fields. This removes ~290 boilerplate annotations with zero serialization behavior changes.The macro was only applied to types where every
Option<T>field already had the annotation, ensuring no behavioral differences.Changes
serde_with = { version = "3", features = ["macros"] }to workspace and protocols dependencies#[serde_with::skip_serializing_none]to qualifying types across 11 files#[serde(skip_serializing_if = "Option::is_none")]from those typesVec::is_empty,HashMap::is_empty) and#[serde(flatten)]Types skipped (not all
Optionfields were annotated — applying the macro would change serialization behavior)OptionField(s)ChatCompletionMessagereasoning_contentNoneasnullChatChoicefinish_reasonnullin response until determinedChatMessageDeltareasoning_contentNoneasnullChatStreamChoicelogprobs,finish_reasonnulluntil final chunkCompletionChoicefinish_reasonChatChoiceCompletionStreamChoicefinish_reasonCompletionStreamResponsesystem_fingerprintResponseInputOutputItemid(inFunctionCallOutput)ResponseContentPartlogprobsResponsesRequeststream#[serde(default)]but no skip — serializesNoneasnullGenerateRequestmodelRerankRequestuserTest Plan
cargo check -p openai-protocolpassesVec::is_empty/HashMap::is_empty/flattenannotations preservedOption::is_noneannotations in transformed typesOption::is_noneannotations remain in non-transformed types (unchanged)Checklist
cargo +nightly fmtpassescargo clippy --all-targets --all-features -- -D warningspassesSummary by CodeRabbit