Skip to content

iter-26: expose Bunny Optimizer pull zone settings#31

Merged
ractive merged 2 commits into
mainfrom
iter-26/optimizer-settings
May 9, 2026
Merged

iter-26: expose Bunny Optimizer pull zone settings#31
ractive merged 2 commits into
mainfrom
iter-26/optimizer-settings

Conversation

@ractive

@ractive ractive commented May 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add the 24 Optimizer* fields from PullZoneModel to PullZone (response) and the 23 writable ones to UpdatePullZone (request); OptimizerPricing stays read-only.
  • Add 23 --optimizer-* flags to pull-zone update under an "Optimizer" help heading, plus an after_help example. New OptimizerWatermarkPosition repr-enum (kebab-case CLI, integer wire).
  • New deserialize_string_lossy_option serde helper so existing fixtures (OptimizerClasses: []) keep deserialising while the writable type stays Option<String>.
  • Tests: wiremock round-trip + per-flag tests (only-set-fields, false-not-skipped, OptimizerMinifyJavaScript long-form key, watermark-position serialised as int) and a CLI integration test asserting the wire body.

Plan deviations

  • OptimizerPricing typed as Option<f64> (not Option<i32> as the plan suggested) — the live pullzone_get.json fixture shows 9.5, so it's a float.
  • OptimizerClasses left as Option<String> per plan, but read-side uses a lenient deserializer that maps non-string values (incl. empty array []) to None to keep existing fixtures working.

Test plan

  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace --quiet
  • Manual smoke: hoppy pull-zone update --help — verify the Optimizer help heading and grouped flags
  • Manual smoke: hoppy pull-zone get --id <id> --format json against a real zone — verify all Optimizer fields surface

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Full Optimizer settings for pull zones via API and CLI: image quality, sizing, WebP/upscaling, minification, manipulation engine, watermarking (including position/offset/min-size), static-HTML caching, prerendering, and tunnel routing. Optimizer pricing returned as read-only.
  • Behavior

    • Tolerant deserialization for optimizer classes (handles string/array) and forward-compatible watermark position handling.
  • Tests

    • End-to-end and CLI tests covering serialization, round-trip, and optimizer flags.
  • Documentation

    • Added guides and quirks for Optimizer fields and mappings.

Add the full Optimizer configuration surface to PullZone (response) and
UpdatePullZone (request), plus 23 --optimizer-* flags on `pull-zone update`.
Operators can now configure Optimizer end-to-end without falling back to
raw curl.

- 24 fields on PullZone (incl. read-only OptimizerPricing as f64)
- 23 writable fields mirrored on UpdatePullZone
- OptimizerWatermarkPosition repr-enum with kebab-case CLI parsing
- deserialize_string_lossy_option helper for OptimizerClasses
  (live API returns [] when empty, plan/docs say string)
- OptimizerPricing typed as Option<f64> not i32 — fixture shows 9.5
- Wiremock + CLI tests covering: only-set-fields serialisation,
  false-not-skipped, OptimizerMinifyJavaScript long-form key,
  watermark-position-as-int, full round-trip

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 9, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Free

Run ID: 3a1a6943-49ab-46e9-b765-d1492f91de64

📥 Commits

Reviewing files that changed from the base of the PR and between 58316c0 and 8548026.

📒 Files selected for processing (2)
  • crates/bunny-api-core/src/types.rs
  • hoppy-knowledgebase/iterations/iteration-26-optimizer-settings.md

📝 Walkthrough

Walkthrough

This PR adds comprehensive support for Bunny Optimizer pull zone settings by extending API types and serde handling, adding CLI flags and handler wiring, introducing e2e and unit tests with fixtures, and updating documentation.

Changes

Optimizer Settings Feature

Layer / File(s) Summary
Serde Deserialization Helper
crates/bunny-api-core/src/serde_helpers.rs
Added deserialize_string_lossy_option to handle API mismatch where OptimizerClasses is documented as string but returns empty array; returns None for non-string JSON values and includes unit tests.
Optimizer Type Definitions
crates/bunny-api-core/src/types.rs
Added OptimizerWatermarkPosition enum (u8 repr) with Display/FromStr; imported new serde helper.
PullZone Response Model
crates/bunny-api-core/src/types.rs
Extended PullZone with many optional optimizer_* fields (enablement, sizing/quality, WebP/upscaling, minify, manipulation engine, classes, watermark, static HTML, prerender, tunnel) and read-only optimizer_pricing.
UpdatePullZone Request Model
crates/bunny-api-core/src/types.rs
Extended UpdatePullZone with matching writable optimizer_* fields (excluding server-set pricing) with serde renames for CSS/JavaScript capitalization.
UpdatePullZone Builder Methods
crates/bunny-api-core/src/types.rs
Added fluent builder methods for each optimizer_* field.
API Serialization Tests & Fixture
crates/bunny-api-core/tests/e2e/pullzone_api.rs, fixtures/core/pullzone_get_with_optimizer.json
Added optimizer-rich fixture and multiple e2e tests validating serialization behavior (only explicit keys included, false preserved, wire naming, enum discriminant) and round-trip deserialization.
CLI Type Definitions
src/cli.rs
Added OptimizerWatermarkPositionArg and grouped --optimizer-* CLI flags mapping to API fields.
CLI Handler Wiring
src/commands/pull_zone.rs
Extended pull_zone handler to destructure optimizer CLI args and apply them to UpdatePullZone via builder methods, converting watermark position.
CLI End-to-End Test
tests/e2e/cli_pull_zone.rs
Added e2e test stubbing POST /pullzone/1001 and running CLI with full optimizer flags to verify payload serialization and success.
Documentation
hoppy-knowledgebase/iterations/iteration-26-optimizer-settings.md, hoppy-knowledgebase/api/bunny-api-quirks.md, hoppy-knowledgebase/decision-log.md, crates/bunny-api-core/src/lib.rs
Added iteration spec, API quirks notes (lossy string handling, repr-enum tolerance, CSS wire-name), decision-log entry, and small lib.rs reformatting.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 A hop through Optimizer lands so fine,
Where watermarks dance in positions divine,
Classes and quality in harmony meet,
Deserialization lossy—oh how neat!
The CLI now speaks what the API needs,
Building and wiring together—our feature succeeds!


Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR expands Hoppy’s bunny-api-core Pull Zone models and CLI to expose bunny.net “Optimizer” configuration end-to-end (read via PullZone, write via UpdatePullZone, and CLI flags on pull-zone update), including handling a known API quirk for OptimizerClasses.

Changes:

  • Add Optimizer fields to PullZone (response) and UpdatePullZone (request), including a new repr-based OptimizerWatermarkPosition enum and explicit wire renames for irregular keys like OptimizerMinifyCSS / OptimizerMinifyJavaScript.
  • Extend hoppy pull-zone update with --optimizer-* flags (grouped under an “Optimizer” help heading) and an after_help example; wire flags to request body fields.
  • Add fixtures + wiremock/CLI tests for round-tripping Optimizer-rich responses and verifying request bodies only include explicitly set Optimizer fields; update e2e JSON snapshots accordingly.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/e2e/snapshots/e2e__cli_pull_zone__pull_zone_list_json.snap Snapshot updated to include Optimizer fields in list JSON output.
tests/e2e/snapshots/e2e__cli_pull_zone__pull_zone_get_json.snap Snapshot updated to include Optimizer fields in get JSON output.
tests/e2e/snapshots/e2e__cli_pull_zone__pull_zone_create_json.snap Snapshot updated to include Optimizer fields surfaced on created zone JSON output.
tests/e2e/cli_pull_zone.rs Adds CLI integration test asserting pull-zone update --optimizer-* flags map to correct wire keys/values.
src/commands/pull_zone.rs Wires new CLI args into UpdatePullZone request construction for pull zone updates.
src/cli.rs Adds --optimizer-* flags and a CLI-only watermark position enum (ValueEnum) plus usage examples.
hoppy-knowledgebase/iterations/iteration-26-optimizer-settings.md Iteration record documenting scope, fields, flags, and tests for Optimizer support.
hoppy-knowledgebase/decision-log.md Records decision to ship full Optimizer surface in one iteration.
hoppy-knowledgebase/api/bunny-api-quirks.md Documents Optimizer API quirks (classes empty array, pricing float, enum may grow, CSS key casing).
fixtures/core/pullzone_get_with_optimizer.json Adds Optimizer-rich fixture used to validate deserialization/serialization behavior.
crates/bunny-api-core/tests/e2e/pullzone_api.rs Adds wiremock tests for Optimizer write semantics and Optimizer-rich read round-trip.
crates/bunny-api-core/src/types.rs Adds Optimizer fields to PullZone/UpdatePullZone and introduces OptimizerWatermarkPosition repr-enum.
crates/bunny-api-core/src/serde_helpers.rs Adds deserialize_string_lossy_option helper + unit tests to tolerate non-string OptimizerClasses.
crates/bunny-api-core/src/lib.rs Re-exports OptimizerWatermarkPosition from the core types module.

Comment thread crates/bunny-api-core/src/types.rs Outdated
Comment on lines +287 to +289
/// Bunny.net may add new positions in future API versions. The CLI uses
/// [`crate::serde_helpers::deserialize_repr_option`] so unknown values
/// deserialise to `None` instead of failing.
**Watermark**
- [x] `optimizer_watermark_enabled: Option<bool>`
- [x] `optimizer_watermark_url: Option<String>`
- [x] `optimizer_watermark_position: Option<i32>` (enum: top-left=0, top-right=1, bottom-left=2, bottom-right=3, center=4 — confirm against spec)
- [x] `optimizer_tunnel_enabled: Option<bool>`

**Read-only (response only — do NOT add to `UpdatePullZone`)**
- [x] `optimizer_pricing: Option<i32>` — appears to be a server-set tier indicator
- Reword OptimizerWatermarkPosition docstring to describe the repr-enum
  forward-compat pattern as a property of the PullZone field deserializer,
  not the CLI.
- Update iteration plan to reflect the actual implemented types:
  optimizer_watermark_position is the OptimizerWatermarkPosition repr-enum,
  optimizer_pricing is Option<f64> (server returns floats like 9.5).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ractive
ractive merged commit 1288c56 into main May 9, 2026
4 of 8 checks passed
@ractive
ractive deleted the iter-26/optimizer-settings branch May 9, 2026 16:19
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