Skip to content

Conversation

@Hinton
Copy link
Member

@Hinton Hinton commented Jan 19, 2026

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-6169

📔 Objective

Improved iteration of bitwarden/sdk-sm#595.

Adds a __Unknown(value) enum to all endpoints to handle any unknown enums in api bindings. Leaving it up to the caller to determine if it should result in a parse error or if there is a graceful way to handle it.

Uses untagged to handle strings and for integers swaps out the serde_repr for a custom macro.

Note: For ease of reviewing this is split into two commits, one that updates the templates and another that updates the bindings. I have not gone through the consumers and updated them yet though.

⏰ Reminders before review

  • Contributor guidelines followed
  • All formatters and local linters executed and passed
  • Written new unit and / or integration tests where applicable
  • Protected functional changes with optionality (feature flags)
  • Used internationalization (i18n) for all UI strings
  • CI builds passed
  • Communicated to DevOps any deployment requirements
  • Updated any necessary documentation (Confluence, contributing docs) or informed the documentation
    team

🦮 Reviewer guidelines

  • 👍 (:+1:) or similar for great changes
  • 📝 (:memo:) or ℹ️ (:information_source:) for notes or general info
  • ❓ (:question:) for questions
  • 🤔 (:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed
    issue and could potentially benefit from discussion
  • 🎨 (:art:) for suggestions / improvements
  • ❌ (:x:) or ⚠️ (:warning:) for more significant problems or concerns needing attention
  • 🌱 (:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt
  • ⛏ (:pick:) for minor or nitpick changes

@Hinton Hinton requested a review from a team as a code owner January 19, 2026 17:07
@Hinton Hinton marked this pull request as draft January 19, 2026 17:07
@github-actions
Copy link
Contributor

github-actions bot commented Jan 19, 2026

🔍 SDK Breaking Change Detection Results

SDK Version: unknown-enum-api (226548f)
Completed: 2026-01-19 17:18:23 UTC
Total Time: 249s

Client Status Details
typescript ✅ No breaking changes detected TypeScript compilation passed with new SDK version - View Details

Breaking change detection completed. View SDK workflow

@github-actions
Copy link
Contributor

github-actions bot commented Jan 19, 2026

Logo
Checkmarx One – Scan Summary & Detailsc53f0175-c0fd-47dd-8eaf-66c5782403e0

Great job! No new security vulnerabilities introduced in this pull request

Copy link
Member

@dani-garcia dani-garcia left a comment

Choose a reason for hiding this comment

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

Sounds like a fairly reasonable solution, I like that we don't lose the unknown value now. A couple of notes:

  • Why name the variant __Unknown rather than just Unknown? The users of this are going to be expected to handle it somehow, so it seems strange when __ could imply internal only.
  • It's a bit strange that the macro is adding an entirely new variant that is not there at all, it could cause some confusion if users check the enum definition and think these enums don't have an unkown branch, only for the compiler to tell them it does have it.
  • Somewhat related, but why use a macro? The code is all autogenerated so we don't really benefit that much from the code duplication, while the macro might make the IDE navigation and code discovery worse.

As a middle ground, if we want to reduce some duplication, I think it would be better to change the templates to generate code like:

#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum KdfType {
    PBKDF2_SHA256 = 0,
    Argon2id = 1,
    Unknown(usize),
}

// Implement these as part of the template, so they're more easily discovered
pub fn as_usize() {}
pub fn from_usize() {}

// The macro implements serialize/deserialize based on the previous functions. This is an implementation detail so it's okay to hide behind a macro
impl_int_enum_deserialize!(KdfType);

@Hinton
Copy link
Member Author

Hinton commented Jan 19, 2026

Why name the variant __Unknown rather than just Unknown? The users of this are going to be expected to handle it somehow, so it seems strange when __ could imply internal only.

It seems Unknown was already used in a server enum 😓. I'm open for any name but apparently we need to take care to avoid conflicts.

It's a bit strange that the macro is adding an entirely new variant that is not there at all, it could cause some confusion if users check the enum definition and think these enums don't have an unkown branch, only for the compiler to tell them it does have it.

Yea fair, I could tweak the bindings to generate it.

Somewhat related, but why use a macro? The code is all autogenerated so we don't really benefit that much from the code duplication, while the macro might make the IDE navigation and code discovery worse.

No reason really. It was nice getting rid of a decent chunk of boilerplate binding code but happy to put it in models.mustche

@Hinton Hinton requested a review from dani-garcia January 20, 2026 10:59
@trmartin4 trmartin4 removed the request for review from dereknance January 20, 2026 21:33
Copy link
Member

@dani-garcia dani-garcia left a comment

Choose a reason for hiding this comment

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

Looks reasonable to me, just needs fixing all the existing uses now

Copy link
Contributor

@coroiu coroiu left a comment

Choose a reason for hiding this comment

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

I have not gone through the consumers and updated them yet though.

@Hinton two questions:

  1. What is your thinking on how the consumers should handle the unknown scenario?
  2. Have you considered making the API enums #[non_exhaustive] to make adding new known types easier in the future?

@Hinton
Copy link
Member Author

Hinton commented Jan 29, 2026

What is your thinking on how the consumers should handle the unknown scenario?

It's up to each team to decide. If they WANT forward compatibility they would have to default to some value. If they don't they can use require!.

Have you considered making the API enums #[non_exhaustive] to make adding new known types easier in the future?

There is benefit in having compile time errors when new enums are added since you definitively know everything supports the new value. Making it non exhaustive would remove this safe guard.

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.

4 participants