Skip to content

AdsClient - refactors request-level sendable options to be client-level - #7743

Open
thesuzerain wants to merge 17 commits into
mainfrom
Ads-client-refactors-sendable-options
Open

thesuzerain wants to merge 17 commits into
mainfrom
Ads-client-refactors-sendable-options

Conversation

@thesuzerain

@thesuzerain thesuzerain commented Nov 6, 2026 •

Copy link
Copy Markdown
Collaborator

Pull Request checklist

  • Breaking changes: This PR follows our breaking change policy
    • This PR follows the breaking change policy:
      • This PR has no breaking API changes, or
      • There are corresponding PRs for our consumer applications that resolve the breaking changes and have been approved
  • Quality: This PR builds and tests run cleanly
    • Note:
      • For changes that need extra cross-platform testing, consider adding [ci full] to the PR title.
      • If this pull request includes a breaking change, consider cutting a new release after merging.
  • Tests: This PR includes thorough tests or an explanation of why it does not
  • Changelog: This PR includes a changelog entry in CHANGELOG.md or an explanation of why it does not need one
    • Any breaking changes to Swift or Kotlin binding APIs are noted explicitly
  • Dependencies: This PR follows our dependency management guidelines
    • Any new dependencies are accompanied by a summary of the due diligence applied in selecting them.

Comment thread components/ads-client/src/ffi.rs Outdated
store_config: Option<MozAdsStoreConfig>,
telemetry: Option<Arc<dyn MozAdsTelemetry>>,
user_agent: Option<NonEmptyString>,
request_options: Option<MozAdsRequestConfigOptions>,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think you need a uniffi default here or that might be a breaking change 🤔

@thesuzerain thesuzerain Nov 9, 2026 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I don't think so, unless I'm missing something or this is on the wrong line. This is a field in MozAdsClientBuilderInner which doesn't cross the uniffi barrier, you explicitly call (eg):

builder().request_options(options).build()

LMK if I have misunderstood!

Comment thread components/ads-client/src/lib.rs Outdated
Comment on lines +147 to +152
let mars_options = options.map(|opt| MARSRequestOptions {
flags: AdRequestFlags::from(&opt),
cache_policy: opt.cache_policy.map(CachePolicy::from).unwrap_or_default(),
ohttp: opt.ohttp,
blocks: opt.blocks,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You repeat this code a couple of times. We could have a From impl and then do options.map(Into::into) I think.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

My reasoning for doing this was I had mixed feelings about using From<> when some of the fields were getting 'lost' (specifically relevance, which would not carry into the new struct). I liked being able to see it explicitly here, but I'm not tied to it, so happy to change this.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

To clarify, this obviously wouldn't affect the code written already. the separate relevance extraction already happens. I meant more in a 'lets not let this field be forgettable in future refactors' kind of change.

But on reflection, I'm not sure how much of a difference it makes to have the Into

Comment thread components/ads-client/src/lib.rs Outdated
new_settings: MozAdsRequestConfigOptions,
) -> AdsClientApiResult<()> {
self.inner
.set_request_options(MARSRequestOptions::from(new_settings));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit but you don't need the ::from call here if you do fn set_request_options(opts: impl Into<MARSRequestOptions>)

@Almaju Almaju left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think there’s a subtle issue with how request options fall back to the configured ones. unwrap_or replaces the whole struct, so if the consumer passes Some(options) with just one field set, all the other fields fall back to their defaults, not to the configured settings.

This is made worse on the FFI side. Because MozAdsRequestConfigOptions uses #[uniffi(default)], a call like { ohttp: true } arrives as { ohttp: true, flags: {}, blocks: [], cache_policy: None }, and the configured flags get erased. I don’t think a consumer would expect that setting one field resets the others.

The root cause is that we can’t distinguish “not provided” from “explicitly empty/false” (e.g. ohttp: bool defaulting to false). What do you think about making the fields optional and merging field by field?

pub struct MozAdsRequestConfigOptions {
    #[uniffi(default)]
    pub blocks: Option<Vec<String>>,
    #[uniffi(default)]
    pub cache_policy: Option<MozAdsCachePolicy>,
    #[uniffi(default)]
    pub flags: Option<HashMap<String, bool>>,
    #[uniffi(default)]
    pub ohttp: Option<bool>,
}

Then each field falls back to the configured value when it’s None.

Also nit: unwrap_or(self.request_options.read().clone()) takes the lock and clones even when options are provided; unwrap_or_else(|| ...) would avoid that.

@thesuzerain

thesuzerain commented Nov 9, 2026 •

Copy link
Copy Markdown
Collaborator Author

This was something I thought a bit about- I leaned towards allowing it and simply forcing each setting to be set (as you'd have easy access to to all of them when you set it on a surface side, and you'd be able to easily set it back to defaults) but you are correct with uniffi defaults it might be misused.

@thesuzerain
thesuzerain marked this pull request as ready for review November 10, 2026 01:25
@thesuzerain
thesuzerain requested a review from a team as a code owner November 10, 2026 01:25

This branch has not been deployed

No deployments
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