Skip to content

feat(options): Derive SentryOptions for typed, live-reloading runtime configuration#425

Open
jan-auer wants to merge 2 commits intofeat/objectstore-optionsfrom
feat/sentry-options-derive
Open

feat(options): Derive SentryOptions for typed, live-reloading runtime configuration#425
jan-auer wants to merge 2 commits intofeat/objectstore-optionsfrom
feat/sentry-options-derive

Conversation

@jan-auer
Copy link
Copy Markdown
Member

@jan-auer jan-auer commented Apr 9, 2026

Stacked on #421.

Separates the generic machinery for typed sentry-options from the Objectstore-specific option types, and introduces a #[derive(SentryOptions)] macro so that adding a new options struct requires no boilerplate.

The work is split following the serde/serde_derive pattern into two new crates:

  • objectstore-typed-options — the SentryOptions trait, shared Error type, and background refresh loop. Exposes a derive feature flag that re-exports the proc macro.
  • objectstore-typed-options-derive — the proc macro, which generates the singleton, get(), init(), and test override support for any annotated struct.

objectstore-options is then reduced to the concrete type definitions, with most of its dependencies removed.

Note: objectstore-typed-options is a prototype intended to be upstreamed into sentry-options itself. The crate boundary makes it easy to iterate on the API before that happens.

Introduces two new crates that replace the hand-written boilerplate in
objectstore-options:

- `objectstore-typed-options` — defines the `SentryOptions` trait, the
  shared `Error` type, and the generic background `refresh` loop. All
  dependencies consumed by generated code (arc-swap, serde, serde_json,
  sentry-options, tokio) are re-exported as hidden items so consumers
  do not need to declare them directly. Exposes a `derive` feature that
  re-exports the proc macro.

- `objectstore-typed-options-derive` — provides `#[derive(SentryOptions)]`,
  which generates the global OnceLock singleton, trait impl, `get()`,
  `init()`, and (under the `testing` feature) `override_with()`. All
  generated paths are fully qualified through `objectstore_typed_options`,
  so the derive can be used from any crate.

`objectstore-options` is reduced to the concrete struct definitions:

- Its dependency list shrinks to `objectstore-typed-options` (with the
  `derive` feature) and `serde`.
- The `init()` free function is gone; callers use `Options::init()`.
@jan-auer jan-auer requested a review from a team as a code owner April 9, 2026 14:12
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2c4aa24. Configure here.

Comment thread objectstore-typed-options-derive/src/lib.rs
Two structs deriving SentryOptions in the same module previously produced
a duplicate symbol error because __OPTIONS was emitted at module scope with
a fixed name. Wrapping all generated items in const _: () = { … } gives
each derived struct its own anonymous scope, matching the standard
serde-style hygiene idiom.
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.

1 participant