Skip to content

fix: add backward-compatible methods to Gray_v08 and GrayAlpha_v08#149

Closed
lilith wants to merge 2 commits intokornelski:mainfrom
lilith:fix-backward-compat-gray-types
Closed

fix: add backward-compatible methods to Gray_v08 and GrayAlpha_v08#149
lilith wants to merge 2 commits intokornelski:mainfrom
lilith:fix-backward-compat-gray-types

Conversation

@lilith
Copy link
Copy Markdown
Contributor

@lilith lilith commented Dec 27, 2025

⚠️ This PR was generated by Claude (Anthropic AI), not by @lilith directly.

Summary

Adds missing methods to legacy Gray types to maintain backward compatibility with dependent crates during the v0.8 → v0.9 → v1.0 migration.

Problem

Several crates broke when upgrading to rgb 0.8.90+ due to missing methods on Gray_v08 and GrayAlpha_v08:

Crate Error Method Needed
resize no method named 'value_mut' Gray.value_mut()
load_image cannot assign to data in dereference GrayAlpha: DerefMut
cavif (depends on load_image) GrayAlpha: DerefMut
dssim (depends on load_image) GrayAlpha: DerefMut

Changes

src/formats/gray.rs - Added to Gray_v08:

pub fn value(self) -> T { self.0 }
pub fn value_mut(&mut self) -> &mut T { &mut self.0 }
pub fn with_alpha(self, alpha: T) -> GrayAlpha_v08<T> { ... }

src/formats/gray_alpha.rs - Added to GrayAlpha_v08:

pub fn value_mut(&mut self) -> &mut T { &mut self.0 }

impl<T, A> DerefMut for GrayAlpha_v08<T, A> {
    fn deref_mut(&mut self) -> &mut GrayA<T, A> {
        unsafe { &mut *(self as *mut Self).cast::<GrayA<T, A>>() }
    }
}

Safety

The DerefMut impl is sound because:

  • Both GrayAlpha_v08<T, A> (tuple: (T, A)) and GrayA<T, A> (struct: { v: T, a: A }) are #[repr(C)]
  • They have identical memory layout
  • The cast just reinterprets the same memory

Testing

Tested with cargo-copter against 224 top rgb dependents:

Status Count Percentage
Passed 155 95.1%
Regressed 8 4.9%
Broken (baseline) 61 N/A

Regression Analysis

Of the 8 regressions found, most are artifacts of forcing a pre-release version and will auto-resolve when 0.8.91 is released as stable:

Category Crates Resolution
Version conflict (auto-resolves) termchat, picterm, inkview-slint, gol-client, aftershock Cargo unifies versions when 0.8.91 is stable
Missing prelude re-export aom-decode, cavif PRs open for yuv and load_image
Internal trait issue load_image Needs IsTransparentPixel trait fix

Key finding: All affected crates already use flexible version constraints (^0.8 or ^0.8.x) that accept 0.8.91. The regressions in testing were caused by forcing a pre-release version while transitive dependencies resolved to 0.8.52 (latest stable), creating type mismatches.

Notable Successes

Major crates working with 0.8.91: image, resvg, oxipng, gifski, femtovg, dssim, butteraugli, mozjpeg, lodepng, imagequant, fast_image_resize, ravif, jpegli-rs

Related

🤖 Generated with Claude Code

Copy link
Copy Markdown
Contributor

@ripytide ripytide left a comment

Choose a reason for hiding this comment

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

I'm fine with adding these methods for the transition to 1.0 but since I don't like them can we mark them as deprecated at least so that we can remove them later?

@lilith
Copy link
Copy Markdown
Contributor Author

lilith commented Dec 27, 2025

Let's wait on adding them until I complete further testing. Turns out some of those baseline failures were actually a bug, and more crates remain affected

@lilith
Copy link
Copy Markdown
Contributor Author

lilith commented Jan 19, 2026

I got a chance to go more carefully through every dependent. I think this should allow publication of the transitional 0.8 release with a low chance of breakage. Only @kornelski really used the deeper parts of this crate in a way that was sensitive to the changes.

@lilith lilith force-pushed the fix-backward-compat-gray-types branch from d36fca7 to 23a15a6 Compare January 19, 2026 05:25
Adds backward-compatible methods for dependent crates during v0.8 → v1.0 migration:

Gray_v08:
- value() - reads .0 field
- value_mut() - mutable access to .0 field
- with_alpha() - creates GrayAlpha_v08

GrayAlpha_v08:
- value_mut() - mutable access to .0 field
- DerefMut impl - allows mutable .v/.a access

All methods marked #[deprecated] to encourage migration to Gray_v09/GrayA.

Tested with cargo-copter against 224 dependents: 95% pass rate.
Regressions are version conflicts that auto-resolve when 0.8.91 is stable.
@lilith lilith force-pushed the fix-backward-compat-gray-types branch from 23a15a6 to 46695fd Compare January 19, 2026 05:42
Comment thread src/formats/gray_alpha.rs
@lilith
Copy link
Copy Markdown
Contributor Author

lilith commented Jan 19, 2026 via email

@lilith
Copy link
Copy Markdown
Contributor Author

lilith commented Feb 7, 2026

Okay, so load_image could actually fix everything in the ecosystem except for the resize crate, which this PR solves (as well as fixing any closed-source or not-on-crates.io crates). I can't fork on codeberg, but the changes are here (which will make it compatible with this version as well as the previous 0.8. lilith/load_image@rgb-prelude-export...fix-rgb-0.8.91-compat

Here's what I think we should do in order

  1. New load_image point release with lilith/load_image@rgb-prelude-export...fix-rgb-0.8.91-compat that works with old and new rgb

  2. New cavif and dssim release that bumps the minimum version of load_image.

  3. Release new 0.8.91 rgb

  4. Next, we hope that nobody updates rgb without updating load_image. Older load_image versions will break with newer rgb, but everything else in the ecosystem should be fine.

  5. Give everyone migration time and slowly bump up the minimum version to force non-crates.io crates to fix any issues. Open PRs for everything to fix deprecation warnings

  6. Release 0.9 or 1.0, do semver trick stuff.

@kornelski kornelski closed this Feb 26, 2026
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.

GrayAlpha<T>.value() missing in main / 0.8.90

3 participants