Format the tree the way the gate asks for it

`cargo fmt --check` is a required step and had drifted across 45 files. Most of
it arrived this week: several operations were written in parallel worktrees and
merged by hand, and a hand-merge resolves conflicts without ever running the
formatter over the result.

No behaviour changes — this is `cargo fmt --all` and nothing else, kept as its
own commit so the next reader can skip it wholesale rather than search it for
one that matters.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-22 21:16:34 +02:00
co-authored by Claude Opus 5
parent d04087af83
commit c75849040c
45 changed files with 545 additions and 257 deletions
+1 -5
View File
@@ -499,11 +499,7 @@ pub fn compose_detail(
// case where a photographer has a kernel switched on at a scale that
// cannot draw it — against the alternative of the preview failing outright
// or `compose_full` growing a resolution argument it has no other use for.
if planned.is_empty()
&& ops
.iter()
.any(|o| o.is_active() && o.detail().is_some())
{
if planned.is_empty() && ops.iter().any(|o| o.is_active() && o.detail().is_some()) {
return ComposedDetail {
passes: vec![compose_one(
RESOLVE_ID,
+10 -4
View File
@@ -8,8 +8,7 @@
//! so reordering the pipeline needs no code change.
use crate::descriptor::{
Attribute,
Facet, LocalizedKey, OpDescriptor, OpId, ParamId, ParamKind, Presentation,
Attribute, Facet, LocalizedKey, OpDescriptor, OpId, ParamId, ParamKind, Presentation,
};
use crate::framing::{CropRect, Framing};
use crate::mask::MaskStack;
@@ -378,7 +377,11 @@ impl EditGraph {
/// Only the detail stage needs this. Every point operation is scale-free
/// — a multiply is a multiply at any resolution — which is why nothing in
/// the pipeline had to know its own size until a kernel arrived.
pub fn render_scale(&self, source: (u32, u32), render: (u32, u32)) -> crate::detail::RenderScale {
pub fn render_scale(
&self,
source: (u32, u32),
render: (u32, u32),
) -> crate::detail::RenderScale {
let (fw, fh) = self.framing.output_size(source.0, source.1);
let view = self.framing.view();
// The *viewed* part of the framed image, at source resolution. Zoom
@@ -397,7 +400,10 @@ impl EditGraph {
/// Empty for every edit with no active neighbourhood operation, which is
/// almost all of them — and in that case [`Self::compose`] emits the
/// single encoded dispatch it always has.
pub fn compose_detail(&self, scale: crate::detail::RenderScale) -> crate::detail::ComposedDetail {
pub fn compose_detail(
&self,
scale: crate::detail::RenderScale,
) -> crate::detail::ComposedDetail {
self.compose_detail_for(scale, dr_types::ColourSpace::Srgb)
}
+2 -2
View File
@@ -44,8 +44,8 @@ pub mod preset;
pub mod sidecar;
pub use descriptor::{
Attribute, Facet, LocalizedKey, OpDescriptor, OpId, ParamDescriptor, ParamId, ParamKind, Presentation,
Scale, Unit, WidgetDemand, WidgetKind,
Attribute, Facet, LocalizedKey, OpDescriptor, OpId, ParamDescriptor, ParamId, ParamKind,
Presentation, Scale, Unit, WidgetDemand, WidgetKind,
};
pub use detail::{
compose_detail, ComposedDetail, ComposedDetailPass, DetailPass, DetailStage, RenderScale,
+30 -10
View File
@@ -856,7 +856,11 @@ impl MaskLayer {
pub fn begin_stroke(&mut self, erase: bool, radius: f32, hardness: f32, flow: f32) -> bool {
let full = self.stroke_points() >= MAX_LAYER_POINTS;
let MaskSource::Brush { strokes } = &mut self.source else {
log::warn!("layer {} is a {} mask, not a brush", self.id, self.source.kind());
log::warn!(
"layer {} is a {} mask, not a brush",
self.id,
self.source.kind()
);
return false;
};
if full {
@@ -1121,7 +1125,10 @@ impl MaskStack {
/// Generate a fresh layer id that does not collide with an existing one.
pub fn next_id(&self) -> String {
(1..).map(|n| format!("m{n}")).find(|id| self.get(id).is_none()).expect("infinite range")
(1..)
.map(|n| format!("m{n}"))
.find(|id| self.get(id).is_none())
.expect("infinite range")
}
}
@@ -1178,10 +1185,7 @@ pub(crate) fn compose_layers(stack: &MaskStack) -> LayerShader {
// place. A second copy here would be a second thing to keep in step
// with `Framing::wgsl_prologue`, and the failure would be a mask that
// is subtly wrong only when straightened.
let _ = writeln!(
out.body,
" var m = sample_mask(uv_src, {slot});"
);
let _ = writeln!(out.body, " var m = sample_mask(uv_src, {slot});");
let _ = writeln!(
out.body,
" m = select(m, 1.0 - m, u.{prefix}_invert > 0.5);"
@@ -1403,7 +1407,11 @@ mod tests {
assert!(shader.uniform_fields.contains("mask1_exposure_"));
assert_eq!(
shader.uniform_values.len(),
shader.uniform_fields.lines().filter(|l| l.trim_start().starts_with("mask")).count(),
shader
.uniform_fields
.lines()
.filter(|l| l.trim_start().starts_with("mask"))
.count(),
"one value per emitted field"
);
}
@@ -1448,7 +1456,11 @@ mod tests {
// A gradient has no region ids, so nothing can go stale about it.
let grad = MaskLayer::new(
"m2",
MaskSource::Linear { centre: (0.5, 0.5), angle: 0.0, width: 0.2 },
MaskSource::Linear {
centre: (0.5, 0.5),
angle: 0.0,
width: 0.2,
},
);
assert!(!grad.is_stale(999));
}
@@ -1458,8 +1470,16 @@ mod tests {
let base = segmentation_signature(1600, 1067, 6730, 2);
assert_eq!(base, segmentation_signature(1600, 1067, 6730, 2));
assert_ne!(base, segmentation_signature(1600, 1067, 6730, 5), "tuning");
assert_ne!(base, segmentation_signature(800, 1067, 6730, 2), "proxy size");
assert_ne!(base, segmentation_signature(1600, 1067, 42, 2), "region count");
assert_ne!(
base,
segmentation_signature(800, 1067, 6730, 2),
"proxy size"
);
assert_ne!(
base,
segmentation_signature(1600, 1067, 42, 2),
"region count"
);
}
#[test]
+5 -5
View File
@@ -472,10 +472,7 @@ pub fn compose_full(
// than from a flag the caller sets, because a caller that got the flag
// wrong would produce a shader whose storage format does not match the
// texture bound to it.
let output_mode = if ops
.iter()
.any(|o| o.is_active() && o.detail().is_some())
{
let output_mode = if ops.iter().any(|o| o.is_active() && o.detail().is_some()) {
OutputMode::LinearWorking
} else {
OutputMode::Encoded
@@ -1389,7 +1386,10 @@ mod tests {
// how a shoulder rolls off.
let mut curve = crate::ops::ToneCurve::new();
curve.set_param(crate::ops::curve::P2_Y, 0.7);
assert!(curve.is_active(), "the fixture must actually reach the shader");
assert!(
curve.is_active(),
"the fixture must actually reach the shader"
);
let source = compose(&[Box::new(curve)]).source;
assert_eq!(
+3 -1
View File
@@ -32,7 +32,9 @@
//! least to perceived sharpness. Scaling all three about a virtual reference
//! would soften the image even when the correction is right.
use crate::descriptor::{Attribute, LocalizedKey, OpDescriptor, OpId, ParamDescriptor, ParamId, Scale, Unit};
use crate::descriptor::{
Attribute, LocalizedKey, OpDescriptor, OpId, ParamDescriptor, ParamId, Scale, Unit,
};
use crate::lens::Warp;
use crate::operation::{Helper, Uniform};
+42 -8
View File
@@ -764,9 +764,11 @@ mod tests {
};
assert_eq!(gate_of(0.0), 0.0);
assert!((gate_of(1.0) - 0.25).abs() < 1e-6);
assert!(chain_at(&sharpening(50.0, 1.0), RenderScale::full((512, 512))).passes[0]
.source
.contains("gate > 0.0"));
assert!(
chain_at(&sharpening(50.0, 1.0), RenderScale::full((512, 512))).passes[0]
.source
.contains("gate > 0.0")
);
}
#[test]
@@ -783,7 +785,11 @@ mod tests {
for scale in scales {
for pass in chain_at(&sharpening(75.0, 1.0), scale).passes {
assert_eq!(pass.uniforms.len() % 4, 0, "{}", pass.label);
assert!(pass.uniforms.iter().all(|v| v.is_finite()), "{}", pass.label);
assert!(
pass.uniforms.iter().all(|v| v.is_finite()),
"{}",
pass.label
);
}
}
}
@@ -805,10 +811,38 @@ mod tests {
// word be safe in one stage and not in the other, which is the sort of
// difference nobody discovers until a shader fails to compile.
const RESERVED: &[&str] = &[
"target", "sample", "filter", "texture", "buffer", "binding", "const", "enum", "mat",
"vec", "ptr", "ref", "shared", "static", "typedef", "union", "unless", "handle",
"layout", "packed", "premerge", "regardless", "active", "do", "input", "output",
"private", "resource", "restrict", "self", "std", "where",
"target",
"sample",
"filter",
"texture",
"buffer",
"binding",
"const",
"enum",
"mat",
"vec",
"ptr",
"ref",
"shared",
"static",
"typedef",
"union",
"unless",
"handle",
"layout",
"packed",
"premerge",
"regardless",
"active",
"do",
"input",
"output",
"private",
"resource",
"restrict",
"self",
"std",
"where",
];
for pass in chain_at(&sharpening(100.0, 2.0), RenderScale::full((512, 512))).passes {
+3 -1
View File
@@ -30,7 +30,9 @@
//! adjusted, each one's share depends on what the other is set to, so turning
//! up one colour's saturation quietly weakened its neighbour's hue shift.
use crate::descriptor::{Attribute, Facet, LocalizedKey, OpDescriptor, OpId, ParamDescriptor, ParamId};
use crate::descriptor::{
Attribute, Facet, LocalizedKey, OpDescriptor, OpId, ParamDescriptor, ParamId,
};
use crate::operation::{Helper, Operation, Uniform};
use crate::ops::helpers;
+8 -8
View File
@@ -121,12 +121,7 @@ impl Channel {
/// Master first because it runs first — see the module documentation for
/// why that is the composition order — and because a list showing the
/// grade before the tone would be describing a different operation.
pub const ALL: [Channel; 4] = [
Channel::Master,
Channel::Red,
Channel::Green,
Channel::Blue,
];
pub const ALL: [Channel; 4] = [Channel::Master, Channel::Red, Channel::Green, Channel::Blue];
/// Position in [`Self::ALL`], and so in every array keyed by channel.
pub const fn index(self) -> usize {
@@ -771,7 +766,10 @@ impl Operation for ToneCurve {
// declared from, so a call and its uniform block cannot disagree
// about a name.
let args = UNIFORM_NAMES[channel.index()].join(", ");
let _ = writeln!(body, "c.{component} = channel_curve(c.{component}, {args});");
let _ = writeln!(
body,
"c.{component} = channel_curve(c.{component}, {args});"
);
}
// Whichever curves ran, the result has to be a colour: the spline's
@@ -1345,7 +1343,9 @@ mod tests {
let body = c.wgsl_body();
let master = body.find("apply_tone_gain").expect("the master curve runs");
let red = body.find("c.r = channel_curve").expect("the red curve runs");
let red = body
.find("c.r = channel_curve")
.expect("the red curve runs");
assert!(master < red, "the master curve must run first:\n{body}");
}
+3 -1
View File
@@ -26,7 +26,9 @@
//! profile is a "make the horizon straight" task, which one term does well.
//! The full triple is reachable by loading a profile.
use crate::descriptor::{Attribute, LocalizedKey, OpDescriptor, OpId, ParamDescriptor, ParamId, Scale, Unit};
use crate::descriptor::{
Attribute, LocalizedKey, OpDescriptor, OpId, ParamDescriptor, ParamId, Scale, Unit,
};
use crate::lens::Warp;
use crate::operation::{Helper, Uniform};
+15 -4
View File
@@ -619,7 +619,10 @@ mod tests {
let scale = RenderScale::full((2000, 1500));
let only_clarity = composed(50.0, 0.0, scale);
assert_eq!(only_clarity.len(), 2, "one operation, two passes");
assert!(only_clarity.passes.iter().all(|p| p.label.starts_with("clarity/")));
assert!(only_clarity
.passes
.iter()
.all(|p| p.label.starts_with("clarity/")));
let both = composed(50.0, 50.0, scale);
assert_eq!(both.len(), 4);
@@ -701,7 +704,10 @@ mod tests {
// acutance family's unit.
let proxy = RenderScale::new((2000, 1500), (6000, 4500));
let clarity = Clarity::with_amount(60.0);
assert_eq!(clarity.kernel(proxy), clarity.kernel(RenderScale::full((2000, 1500))));
assert_eq!(
clarity.kernel(proxy),
clarity.kernel(RenderScale::full((2000, 1500)))
);
assert!(
proxy.source_pixels(96.0) < 40.0,
"the same length in the other unit would have collapsed"
@@ -786,7 +792,9 @@ mod tests {
// slider can produce is `gain * threshold` stops however violent the
// edge — a bound that holds by construction rather than by tuning.
let combine = &Clarity::with_amount(100.0).passes(RenderScale::full((2000, 1500)))[1];
assert!(combine.wgsl.contains("threshold * tanh(detail / threshold)"));
assert!(combine
.wgsl
.contains("threshold * tanh(detail / threshold)"));
let bound = |u: &[Uniform]| {
let get = |n| u.iter().find(|x| x.name == n).unwrap().value;
@@ -819,7 +827,10 @@ mod tests {
// And texture does not carry the helpers it would need for one, so its
// shader says what it does rather than merely not calling it.
assert!(Texture::new().helpers().iter().any(|h| h.name == "log_luma"));
assert!(Texture::new()
.helpers()
.iter()
.any(|h| h.name == "log_luma"));
assert!(!Texture::new()
.helpers()
.iter()
+7 -1
View File
@@ -820,7 +820,13 @@ mod tests {
// Everything else about the two must match, or one axis is filtered
// harder than the other and a round blotch comes out oval.
assert_eq!(passes[0].radius, passes[1].radius);
for name in ["radius", "inv_spatial", "guide_k", "chroma_k", "noise_floor"] {
for name in [
"radius",
"inv_spatial",
"guide_k",
"chroma_k",
"noise_floor",
] {
let of = |p: &DetailPass| {
p.uniforms
.iter()
+6 -5
View File
@@ -67,9 +67,7 @@ use std::fmt;
use std::fmt::Write as _;
use crate::graph::EditGraph;
use crate::mask::{
Falloff, MaskLayer, MaskSource, MaskStack, Morphology, Stroke, DEFAULT_FEATHER,
};
use crate::mask::{Falloff, MaskLayer, MaskSource, MaskStack, Morphology, Stroke, DEFAULT_FEATHER};
use crate::preset::{resolve, Preset};
/// Format version of the document itself.
@@ -662,7 +660,6 @@ impl Sidecar {
}
}
/// Write one mask layer as its own block.
///
/// The version uuid is repeated in the header rather than relying on the
@@ -1292,7 +1289,11 @@ mod tests {
// else.
assert_eq!(g.param(curve::ID, curve::P1_Y), Some(0.15));
assert_eq!(g.param(curve::ID, curve::P3_Y), Some(0.85));
for channel in [curve::Channel::Red, curve::Channel::Green, curve::Channel::Blue] {
for channel in [
curve::Channel::Red,
curve::Channel::Green,
curve::Channel::Blue,
] {
for point in 0..curve::POINTS {
for axis in [curve::Axis::X, curve::Axis::Y] {
let id = curve::coordinate(channel, point, axis);