Skip to content

Surface the psnr field on ImageResult - #11

Merged
mathiasgrimm merged 2 commits into
mainfrom
feat/psnr-field
Aug 2, 2026
Merged

Surface the psnr field on ImageResult#11
mathiasgrimm merged 2 commits into
mainfrom
feat/psnr-field

Conversation

@mathiasgrimm

Copy link
Copy Markdown
Owner

SDK side of Art-Commerce-Systems/glimpseimg.com#91 (API PR: Art-Commerce-Systems/glimpseimg.com#98).

What

  • ImageResult gains public ?float $psnr = null as the last promoted constructor parameter. The default keeps new ImageResult(...) backward compatible for positional and named-argument callers, which is the only non-breaking option on a readonly class.
  • fromResponse() maps the field with the same null-guard idiom as SizeEstimate::$quality, so an absent or null field never coerces to 0.0.
  • No Client changes: the response data array already flows into fromResponse().
  • Tests: psnr surfaced on convert, null passthrough, absent-field (resize shape) maps to null, integer cast to float.

Rollout

Merge after the API PR. Works against old and new API alike (the field is just null against an older API). Suggested release: v3.1.0 (additive, minor). glimpse-cli v1.4.0 will require ^3.1.

Verification

composer test passes: 52 tests, 151 assertions.

🤖 Generated with Claude Code

The API's optimize and convert responses now carry psnr, the peak
signal-to-noise ratio in decibels between the input and the output.
The property defaults to null and sits last in the constructor, so
existing positional and named-argument construction keeps working.
Responses without the field (resize, thumbnail, older API versions)
map to null.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds a test asserting the pre-3.1 six-argument constructor still works
and defaults psnr to null, so the additive parameter cannot silently
become a breaking change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mathiasgrimm

Copy link
Copy Markdown
Owner Author

Two independent reviews, one by a Claude agent and one by codex (gpt-5.6-sol, read-only). Both approve with no blocking findings. Codex's one optional suggestion (a test that directly constructs ImageResult with the pre-3.1 six arguments and asserts psnr is null) was added in commit c9d3714 to lock the backward-compatibility guarantee.


Claude review

Verdict: clean and safe to ship as v3.1.0. No blocking findings.

What I verified

  • Backward compatibility. ?float $psnr = null is the last promoted parameter with a default, so existing six-argument positional calls and all named-argument calls keep working. The class is final readonly, so there is no inheritance surface. fromResponse() keeps its signature. The default is a deliberate, correct divergence from SizeEstimate::$quality (required, no default): ImageResult's constructor is already released public API, so the default is what makes this an additive minor.
  • Null-guard mapping. $psnr === null ? null : (float) $psnr is the exact idiom used for SizeEstimate::$quality. data_get($data, 'psnr') is correct: Client::post() returns the unwrapped data object. The (float) cast also protects against a JSON integer reaching the typed parameter.
  • Test coverage. The cases cover float round-trip, explicit null, absent field (via resize, which really lacks the field), and integer-to-float. The $overrides + $defaults union keeps a left-side null key, so "present with null" and "absent" are genuinely distinct fixtures.
  • Docblock matches the API behavior and follows the project writing rules.
  • Suite: composer test passes end to end. Pint clean, PHPStan clean, 52 tests / 151 assertions green.

Minor notes

  • Not for this PR: fromResponse() maps a non-numeric string to 0.0 rather than null, matching the tolerant casting of every other field in both mappers. Only worth revisiting if the mappers get stricter as a group.

Codex review

Verdict: Approve. The change is correct, convention-consistent, and appropriate for the additive v3.1.0 release.

Critical: None. Major: None. Minor: None.

Minor notes

  • Adding the optional parameter last preserves existing six-argument positional and named constructor calls.
  • The null guard and float cast correctly match the SizeEstimate::$quality mapping idiom.
  • The docblock accurately describes units, endpoint availability, meaning, and null behavior.
  • Coverage includes float mapping, integer casting, explicit null, and an absent field. A separate thumbnail test would add little because all transform endpoints share ImageResult::fromResponse().
  • Optional coverage improvement: directly construct ImageResult with the original six arguments and assert psnr is null, explicitly locking constructor compatibility. (Added in c9d3714.)
  • Narrow caveat: PHP objects serialized before v3.1 would deserialize with psnr uninitialized. The project does not document native serialization as supported, so this is not blocking.

Validation: 52 tests / 151 assertions passed, syntax checks clean, git diff --check clean.

@mathiasgrimm
mathiasgrimm merged commit b556472 into main Aug 2, 2026
6 checks passed
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