authorclover caruso <git@paperclover.net> 2026-10-10 20:23:39-07:00
committerclover caruso <git@paperclover.net> 2026-10-10 22:56:05-07:00
log3bc26d2f339e409b94776447c6d0cd661d5da6ff
tree1f703754fccd4c76e2ebe209e02fb4883bb583ec
parente9d0ff1435aa931d38788bf676968c992e370104
signature Signed by SSH key SHA256:52mNGHRsVFBDED9IAX5pe+LRWUefqTbxEReunq21QvU (~clover)

chore: use array chunks for fixed-size iteration

Replace constant-size chunks_exact iterators with as_chunks, preserving remainder handling and mutable iteration. Keep runtime-size chunking unchanged. Assisted-by: gpt-6.1-sol

39 files changed, 197 insertions(+), 114 deletions(-)

crates/canvas/src/gpu/page/background.rs+15-4
......@@ -599,7 +599,9 @@ pub fn template_picture(name: &str) -> Option<Vec<u8>> {
599599 let [width, height] = [view.width(), view.height()].map(|side| side.round() as u32);
600600 // Over white paper, as OneNote's pictures are drawn.
601601 let rgb: Vec<u8> = render(template.svg, [width, height])
602 .chunks_exact(4)
602 .as_chunks::<4>()
603 .0
604 .iter()
603605 .flat_map(|pixel| {
604606 let alpha = u16::from(pixel[3]);
605607 [0, 1, 2].map(|channel| {
......@@ -624,12 +626,16 @@ pub fn template_picture(name: &str) -> Option<Vec<u8>> {
624626 } else {
625627 // OneNote's PNG templates hold 256 colours.
626628 let rgba: Vec<u8> = rgb
627 .chunks_exact(3)
629 .as_chunks::<3>()
630 .0
631 .iter()
628632 .flat_map(|pixel| [pixel[0], pixel[1], pixel[2], 255])
629633 .collect();
630634 let quantized = color_quant::NeuQuant::new(10, 256, &rgba);
631635 let indices: Vec<u8> = rgba
632 .chunks_exact(4)
636 .as_chunks::<4>()
637 .0
638 .iter()
633639 .map(|pixel| quantized.index_of(pixel) as u8)
634640 .collect();
635641 let mut encoder = png::Encoder::new(&mut encoded, width, height);
......@@ -1044,7 +1050,12 @@ mod tests {
10441050 })
10451051 .unwrap();
10461052 let pixels = readback.get_mapped_range(..).unwrap().to_vec();
1047 let pixels: Vec<[u8; 3]> = pixels.chunks_exact(4).map(|p| [p[0], p[1], p[2]]).collect();
1053 let pixels: Vec<[u8; 3]> = pixels
1054 .as_chunks::<4>()
1055 .0
1056 .iter()
1057 .map(|p| [p[0], p[1], p[2]])
1058 .collect();
10481059 assert!(
10491060 pixels
10501061 .iter()
crates/canvas/src/gpu/tag_art.rs+1-1
......@@ -87,7 +87,7 @@ fn raster(tree: &usvg::Tree) -> Option<Vec<u8>> {
8787 [color.red(), color.green(), color.blue(), color.alpha()]
8888 })
8989 .collect();
90 if rgba.chunks_exact(4).all(|pixel| pixel[3] == 0) {
90 if rgba.as_chunks::<4>().0.iter().all(|pixel| pixel[3] == 0) {
9191 return None;
9292 }
9393 Some(png(&image::RgbaImage::from_raw(width, height, rgba)?))
crates/canvas/src/recording.rs+4-2
......@@ -204,7 +204,9 @@ pub fn compress(wav: &[u8]) -> Option<(Vec<u8>, u32)> {
204204 }
205205 let samples: Vec<i16> = wave
206206 .data
207 .chunks_exact(2)
207 .as_chunks::<2>()
208 .0
209 .iter()
208210 .map(|pair| i16::from_le_bytes([pair[0], pair[1]]))
209211 .collect();
210212 let mut data = Vec::with_capacity(samples.len() / 2 + BLOCK);
......@@ -221,7 +223,7 @@ pub fn compress(wav: &[u8]) -> Option<(Vec<u8>, u32)> {
221223 .chain(std::iter::repeat(last))
222224 .take(BLOCK_SAMPLES - 1)
223225 .collect::<Vec<_>>();
224 for pair in rest.chunks_exact(2) {
226 for pair in rest.as_chunks::<2>().0 {
225227 let mut byte = 0;
226228 for (shift, sample) in [0, 4].into_iter().zip(pair) {
227229 let code = encode(i32::from(*sample), &mut predicted, &mut index);
crates/canvas/src/recording/video.rs+3-1
......@@ -359,7 +359,9 @@ impl Pictures {
359359 .take(height)
360360 .filter_map(|row| row.get(..width * 4))
361361 .flat_map(|row| {
362 row.chunks_exact(4)
362 row.as_chunks::<4>()
363 .0
364 .iter()
363365 .flat_map(|pixel| [pixel[2], pixel[1], pixel[0]])
364366 })
365367 .collect();
crates/draw/src/render.rs+4-2
......@@ -107,7 +107,7 @@ fn decoder(encoded: &[u8]) -> Result<impl ImageDecoder + '_, RenderError> {
107107/// Premultiplies straight-alpha sRGB RGBA in linear light, so filtering never bleeds the
108108/// colour of transparent pixels.
109109fn premultiply(pixels: &mut [u8]) {
110 for pixel in pixels.chunks_exact_mut(4) {
110 for pixel in pixels.as_chunks_mut::<4>().0 {
111111 let alpha = pixel[3];
112112 if alpha == 255 {
113113 continue;
......@@ -2349,7 +2349,9 @@ mod tests {
23492349 assert_eq!(renderer.glyphs.len(), count);
23502350 assert!(
23512351 captures[0]
2352 .chunks_exact(4)
2352 .as_chunks::<4>()
2353 .0
2354 .iter()
23532355 .filter(|pixel| pixel[0] < 200)
23542356 .count()
23552357 > 100
crates/draw/src/render/canvas2d.rs+3-3
......@@ -236,7 +236,7 @@ impl Gpu {
236236 .filter(|batch| batch.blend == Blend::Over);
237237 for batch in batches {
238238 let range = batch.vertices.start as usize..batch.vertices.end as usize;
239 for quad in frame.vertices[range].chunks_exact(6) {
239 for quad in frame.vertices[range].as_chunks::<6>().0 {
240240 let Some(color) = tinted(quad) else {
241241 continue;
242242 };
......@@ -320,7 +320,7 @@ impl Gpu {
320320 // The canvas takes straight alpha; the picture's colour was premultiplied in linear
321321 // light.
322322 let mut pixels = image.pixels().to_vec();
323 for pixel in pixels.chunks_exact_mut(4) {
323 for pixel in pixels.as_chunks_mut::<4>().0 {
324324 let alpha = f32::from(pixel[3]) / 255.0;
325325 if alpha > 0.0 && alpha < 1.0 {
326326 for byte in &mut pixel[..3] {
......@@ -613,7 +613,7 @@ impl<'a> Painter<'a> {
613613 self.set_clip(None);
614614 return self.group(index, vertices);
615615 }
616 for quad in vertices.chunks_exact(6) {
616 for quad in vertices.as_chunks::<6>().0 {
617617 let clip = self.clip_of(batch.scissor, quad);
618618 self.set_clip(clip);
619619 match batch.blend {
crates/draw/src/render/icon.rs+13-4
......@@ -627,18 +627,27 @@ mod tests {
627627 image.data.len(),
628628 (image.placement.width * image.placement.height * 4) as usize
629629 );
630 assert!(image.data.chunks_exact(4).any(|p| p[3] > 0));
631 assert!(image.data.chunks_exact(4).any(|p| p[3] < 255));
630 assert!(image.data.as_chunks::<4>().0.iter().any(|p| p[3] > 0));
631 assert!(image.data.as_chunks::<4>().0.iter().any(|p| p[3] < 255));
632632 assert!(
633633 image
634634 .data
635 .chunks_exact(4)
635 .as_chunks::<4>()
636 .0
637 .iter()
636638 .filter(|p| p[3] == 0)
637639 .all(|p| p[..3] == [0; 3])
638640 );
639641 }
640642 assert_ne!(plain.data, marked.data);
641 assert!(marked.data.chunks_exact(4).any(|p| p[0] > p[2] && p[3] > 0));
643 assert!(
644 marked
645 .data
646 .as_chunks::<4>()
647 .0
648 .iter()
649 .any(|p| p[0] > p[2] && p[3] > 0)
650 );
642651 }
643652 }
644653}
crates/draw/src/render/pdf.rs+38-18
......@@ -639,7 +639,9 @@ impl Document {
639639 // Pixels are premultiplied in linear light.
640640 let straight: Vec<u8> = image
641641 .pixels()
642 .chunks_exact(4)
642 .as_chunks::<4>()
643 .0
644 .iter()
643645 .flat_map(|pixel| {
644646 let alpha = pixel[3];
645647 if alpha == 255 || alpha == 0 {
......@@ -653,10 +655,16 @@ impl Document {
653655 })
654656 .collect();
655657 let size = image.size();
656 let opaque = straight.chunks_exact(4).all(|pixel| pixel[3] == 255);
658 let opaque = straight
659 .as_chunks::<4>()
660 .0
661 .iter()
662 .all(|pixel| pixel[3] == 255);
657663 if opaque && size[0] * size[1] >= 64 * 64 {
658664 let rgb: Vec<u8> = straight
659 .chunks_exact(4)
665 .as_chunks::<4>()
666 .0
667 .iter()
660668 .flat_map(|pixel| [pixel[0], pixel[1], pixel[2]])
661669 .collect();
662670 let mut jpeg = Vec::new();
......@@ -688,23 +696,35 @@ impl Document {
688696 /// Straight sRGB RGBA pixels as a losslessly compressed image XObject.
689697 fn image(&mut self, [width, height]: [u32; 2], rgba: &[u8], interpolate: bool) -> Ref {
690698 let rgb: Vec<u8> = rgba
691 .chunks_exact(4)
699 .as_chunks::<4>()
700 .0
701 .iter()
692702 .flat_map(|pixel| [pixel[0], pixel[1], pixel[2]])
693703 .collect();
694 let mask = rgba.chunks_exact(4).any(|pixel| pixel[3] != 255).then(|| {
695 let alpha: Vec<u8> = rgba.chunks_exact(4).map(|pixel| pixel[3]).collect();
696 let mask = self.reserve();
697 let data = compress(&alpha);
698 let mut writer = self.pdf.image_xobject(mask, &data);
699 writer.filter(Filter::FlateDecode);
700 writer
701 .width(width as i32)
702 .height(height as i32)
703 .color_space_name(Name(b"DeviceGray"))
704 .bits_per_component(8)
705 .interpolate(interpolate);
706 mask
707 });
704 let mask = rgba
705 .as_chunks::<4>()
706 .0
707 .iter()
708 .any(|pixel| pixel[3] != 255)
709 .then(|| {
710 let alpha: Vec<u8> = rgba
711 .as_chunks::<4>()
712 .0
713 .iter()
714 .map(|pixel| pixel[3])
715 .collect();
716 let mask = self.reserve();
717 let data = compress(&alpha);
718 let mut writer = self.pdf.image_xobject(mask, &data);
719 writer.filter(Filter::FlateDecode);
720 writer
721 .width(width as i32)
722 .height(height as i32)
723 .color_space_name(Name(b"DeviceGray"))
724 .bits_per_component(8)
725 .interpolate(interpolate);
726 mask
727 });
708728 let reference = self.reserve();
709729 let data = compress(&rgb);
710730 let mut writer = self.pdf.image_xobject(reference, &data);
crates/mobile/src/tests.rs+4-1
......@@ -968,7 +968,10 @@ fn tag_icons_draw_their_art_and_highlighting_tags_have_none() {
968968 let drawn = unsafe { sb_tag_icon(tag.shape, true, 32, rgba.as_mut_ptr()) };
969969 assert_eq!(drawn, tag.shape != 0, "{tag:?}");
970970 if drawn {
971 assert!(rgba.chunks_exact(4).any(|pixel| pixel[3] > 0), "{tag:?}");
971 assert!(
972 rgba.as_chunks::<4>().0.iter().any(|pixel| pixel[3] > 0),
973 "{tag:?}"
974 );
972975 }
973976 }
974977}
crates/notebook/examples/externalize_fixture.rs+4-2
......@@ -35,8 +35,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
3535 u32::from_le_bytes(encoded[offset..offset + 4].try_into()?) as usize;
3636 let text = String::from_utf16(
3737 &encoded[offset + 4..offset + 4 + count * 2]
38 .chunks_exact(2)
39 .map(|v| u16::from_le_bytes(v.try_into().unwrap()))
38 .as_chunks::<2>()
39 .0
40 .iter()
41 .map(|v| u16::from_le_bytes(*v))
4042 .collect::<Vec<_>>(),
4143 )?;
4244 if let FileDataReference::Internal(guid) = text.parse()? {
crates/notebook/src/smb/directory/records.rs+3-1
......@@ -34,7 +34,9 @@ pub(super) fn decode(mut bytes: &[u8]) -> io::Result<Vec<DirectoryEntry>> {
3434 return Err(io::ErrorKind::InvalidData.into());
3535 }
3636 let units: Vec<_> = bytes[64..end]
37 .chunks_exact(2)
37 .as_chunks::<2>()
38 .0
39 .iter()
3840 .map(|unit| u16::from_le_bytes([unit[0], unit[1]]))
3941 .collect();
4042 let name = String::from_utf16(&units).map_err(|_| io::ErrorKind::InvalidData)?;
crates/notebook/tests/structure.rs+3-1
......@@ -146,7 +146,9 @@ fn sections_and_groups_are_created_renamed_coloured_ordered_and_deleted() {
146146 let bin = onestore::read_file(root.join("OneNote_RecycleBin/Open Notebook.onetoc2")).unwrap();
147147 assert!(
148148 String::from_utf16_lossy(
149 &bin.chunks_exact(2)
149 &bin.as_chunks::<2>()
150 .0
151 .iter()
150152 .map(|c| u16::from_le_bytes([c[0], c[1]]))
151153 .collect::<Vec<_>>()
152154 )
crates/notebook/tests/support/model_schedule.rs+1-1
......@@ -189,7 +189,7 @@ pub fn run(input: &[u8]) {
189189 let directory = tempfile::tempdir().unwrap();
190190 let mut replicas: [Option<Replica>; 12] = std::array::from_fn(|_| None);
191191 let mut server = Server::new(source);
192 for step in input.chunks_exact(8).take(48) {
192 for step in input.as_chunks::<8>().0.iter().take(48) {
193193 let actor = usize::from(step[0]) % replicas.len();
194194 let path = directory.path().join(format!("{actor}.sqlite"));
195195 let cache = replicas[actor].get_or_insert_with(|| Replica::create(&path, source).unwrap());
crates/notebook/tests/support/page_schedule.rs+1-1
......@@ -118,7 +118,7 @@ pub fn run(input: &[u8]) {
118118 write_limit: 4096,
119119 random: 1,
120120 };
121 for step in input.chunks_exact(8).take(48) {
121 for step in input.as_chunks::<8>().0.iter().take(48) {
122122 let actor = usize::from(step[0]) % replicas.len();
123123 let path = directory.path().join(format!("{actor}.sqlite"));
124124 let cache = replicas[actor].get_or_insert_with(|| Replica::create(&path, &SOURCE).unwrap());
crates/notebook/tests/sync_pages.rs+1-1
......@@ -557,7 +557,7 @@ fn twelve_disjoint_page_batches_merge_with_dependent_bodies_without_review() {
557557 let mut expected_text = texts(&source);
558558 let directory = tempfile::tempdir().unwrap();
559559 let mut queues = Vec::new();
560 for (actor, group) in created.chunks_exact(3).enumerate() {
560 for (actor, group) in created.as_chunks::<3>().0.iter().enumerate() {
561561 let path = directory.path().join(format!("{actor}.sqlite"));
562562 let cache = Replica::create(&path, &source).unwrap();
563563 let edits = [
crates/onestore/examples/edit_property.rs+4-2
......@@ -18,7 +18,9 @@ fn hex(text: &str) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
1818 return Err("Expected an even number of hexadecimal digits".into());
1919 }
2020 text.as_bytes()
21 .chunks_exact(2)
21 .as_chunks::<2>()
22 .0
23 .iter()
2224 .map(|pair| Ok(u8::from_str_radix(std::str::from_utf8(pair)?, 16)?))
2325 .collect()
2426}
......@@ -69,7 +71,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
6971 (0x6000e, 0x1c001c22) => {
7072 let units = |bytes: &[u8]| -> Vec<u16> {
7173 let mut units: Vec<u16> = bytes
72 .chunks_exact(2)
74 .as_chunks::<2>().0.iter()
7375 .map(|pair| u16::from_le_bytes([pair[0], pair[1]]))
7476 .collect();
7577 if units.last() == Some(&0) {
crates/onestore/src/create.rs+2-4
......@@ -456,10 +456,8 @@ fn create(file_name: &str, file_type: FileType, spaces: Vec<NewSpace>) -> Result
456456 for object in &space.objects {
457457 for (property, value) in &object.properties {
458458 if matches!((property >> 26) & 0x1f, 8 | 9) {
459 for id in value.chunks_exact(4) {
460 *counts
461 .entry(u32::from_le_bytes(id.try_into().unwrap()))
462 .or_default() += 1;
459 for id in value.as_chunks::<4>().0 {
460 *counts.entry(u32::from_le_bytes(*id)).or_default() += 1;
463461 }
464462 }
465463 }
crates/onestore/src/document.rs+21-14
......@@ -629,8 +629,10 @@ fn unicode(bytes: &[u8]) -> Result<String> {
629629 return Err(invalid("Odd UTF-16 document string length"));
630630 }
631631 let units: Vec<_> = bytes
632 .chunks_exact(2)
633 .map(|x| u16::from_le_bytes(x.try_into().unwrap()))
632 .as_chunks::<2>()
633 .0
634 .iter()
635 .map(|x| u16::from_le_bytes(*x))
634636 .collect();
635637 String::from_utf16(units.strip_suffix(&[0]).unwrap_or(&units))
636638 .map_err(|_| invalid("Invalid UTF-16 document string"))
......@@ -690,10 +692,7 @@ impl<'a, 'o> Fields<'a, 'o> {
690692 if !bytes.len().is_multiple_of(16) {
691693 return Err(invalid("Media identifiers have an invalid length"));
692694 }
693 Ok(bytes
694 .chunks_exact(16)
695 .map(|id| id.try_into().unwrap())
696 .collect())
695 Ok(bytes.as_chunks::<16>().0.to_vec())
697696 }
698697 fn u16(&mut self, id: u32) -> Result<Option<u16>> {
699698 Ok(self.fixed(id)?.map(u16::from_le_bytes))
......@@ -775,10 +774,12 @@ fn references(bytes: &[u8], ids: &BTreeMap<u32, [u8; 16]>) -> Result<Vec<ExGuid>
775774 {
776775 let table: Vec<[u8; 16]> = ids.values().copied().collect();
777776 return bytes
778 .chunks_exact(4)
777 .as_chunks::<4>()
778 .0
779 .iter()
779780 .enumerate()
780781 .map(|(i, bytes)| {
781 let raw = u32::from_le_bytes(bytes.try_into().unwrap());
782 let raw = u32::from_le_bytes(*bytes);
782783 let guid = table.get((raw >> 8) as usize).ok_or(Error {
783784 offset: i * 4,
784785 message: "Compact ID refers to a missing global ID",
......@@ -814,8 +815,10 @@ fn measurements(bytes: Option<&[u8]>, header: usize) -> Result<Vec<f32>> {
814815 return Err(invalid("Document measurement array has an invalid length"));
815816 }
816817 bytes[header..]
817 .chunks_exact(4)
818 .map(|b| finite(f32::from_le_bytes(b.try_into().unwrap()) * 36.0))
818 .as_chunks::<4>()
819 .0
820 .iter()
821 .map(|b| finite(f32::from_le_bytes(*b) * 36.0))
819822 .collect()
820823}
821824
......@@ -1220,8 +1223,10 @@ impl<'a> Element<'a> {
12201223 }
12211224 bounds.extend(
12221225 bytes
1223 .chunks_exact(4)
1224 .map(|b| u32::from_le_bytes(b.try_into().unwrap())),
1226 .as_chunks::<4>()
1227 .0
1228 .iter()
1229 .map(|b| u32::from_le_bytes(*b)),
12251230 );
12261231 }
12271232 bounds.push(length);
......@@ -1292,8 +1297,10 @@ impl<'a> Element<'a> {
12921297 return Err(invalid("List format has an invalid length"));
12931298 }
12941299 let units = bytes[2..]
1295 .chunks_exact(2)
1296 .map(|b| u16::from_le_bytes(b.try_into().unwrap()))
1300 .as_chunks::<2>()
1301 .0
1302 .iter()
1303 .map(|b| u16::from_le_bytes(*b))
12971304 .collect::<Vec<_>>();
12981305 String::from_utf16(&units)
12991306 .map_err(|_| invalid("Invalid UTF-16 list format"))
crates/onestore/src/files.rs+3-1
......@@ -41,7 +41,9 @@ impl Object<'_> {
4141 }
4242 let text = String::from_utf16(
4343 &reference
44 .chunks_exact(2)
44 .as_chunks::<2>()
45 .0
46 .iter()
4547 .map(|pair| u16::from_le_bytes([pair[0], pair[1]]))
4648 .collect::<Vec<_>>(),
4749 )
crates/onestore/src/page/ink.rs+11-4
......@@ -295,7 +295,12 @@ impl InkStroke {
295295 if dimensions.len() % 32 != 0 || dimensions.is_empty() {
296296 return Err(invalid("Ink dimension table has an invalid length"));
297297 }
298 let entries: Vec<&[u8]> = dimensions.chunks_exact(32).collect();
298 let entries: Vec<&[u8]> = dimensions
299 .as_chunks::<32>()
300 .0
301 .iter()
302 .map(|entry| entry.as_slice())
303 .collect();
299304 let axis = |guid: &[u8]| entries.iter().position(|entry| entry[..16] == *guid);
300305 let (Some(x), Some(y)) = (axis(&DIMENSION_X), axis(&DIMENSION_Y)) else {
301306 return Err(invalid("Ink dimension table lacks X and Y"));
......@@ -365,8 +370,10 @@ impl InkShape {
365370 fn read(kind: Option<u8>, line: Option<&[u8]>, anchors: Option<&[u8]>) -> Option<Self> {
366371 let floats = |bytes: &[u8]| -> Vec<f32> {
367372 bytes
368 .chunks_exact(4)
369 .map(|b| f32::from_le_bytes(b.try_into().unwrap()))
373 .as_chunks::<4>()
374 .0
375 .iter()
376 .map(|b| f32::from_le_bytes(*b))
370377 .collect()
371378 };
372379 match (kind?, line, anchors) {
......@@ -381,7 +388,7 @@ impl InkShape {
381388 let v = floats(bytes);
382389 Some(Self::Closed {
383390 transform: std::array::from_fn(|i| v[i] * 36.0),
384 anchors: v[6..].chunks_exact(2).map(|p| [p[0], p[1]]).collect(),
391 anchors: v[6..].as_chunks::<2>().0.to_vec(),
385392 })
386393 .filter(Self::finite)
387394 }
crates/onestore/src/page/mod.rs+3-1
......@@ -589,7 +589,9 @@ impl Image {
589589 })
590590 .map(|bytes| {
591591 let units: Vec<u16> = bytes
592 .chunks_exact(2)
592 .as_chunks::<2>()
593 .0
594 .iter()
593595 .map(|pair| u16::from_le_bytes([pair[0], pair[1]]))
594596 .collect();
595597 String::from_utf16_lossy(&units)
crates/onestore/src/paragraph.rs+4-2
......@@ -575,8 +575,10 @@ impl ParagraphJoin {
575575 }
576576 ends.truncate(ends.len() - 4);
577577 if ends
578 .chunks_exact(4)
579 .map(|bytes| u32::from_le_bytes(bytes.try_into().unwrap()))
578 .as_chunks::<4>()
579 .0
580 .iter()
581 .map(|bytes| u32::from_le_bytes(*bytes))
580582 .collect::<Vec<_>>()
581583 .windows(2)
582584 .any(|pair| pair[0] >= pair[1])
crates/onestore/src/store.rs+1-1
......@@ -640,7 +640,7 @@ impl<'a> Store<'a> {
640640 max_list: self
641641 .transaction_fragments
642642 .iter()
643 .flat_map(|fragment| fragment.entries.chunks_exact(8))
643 .flat_map(|fragment| fragment.entries.as_chunks::<8>().0.iter())
644644 .map(|entry| u32::from_le_bytes(entry[..4].try_into().unwrap()))
645645 .max()
646646 .unwrap(),
crates/onestore/src/write.rs+15-13
......@@ -140,8 +140,10 @@ pub(crate) fn table_entries(bytes: &[u8]) -> Result<Vec<u32>> {
140140 if let Value::References { compact_ids, .. } = property.value {
141141 entries.extend(
142142 compact_ids
143 .chunks_exact(4)
144 .map(|id| u32::from_le_bytes(id.try_into().unwrap()) >> 8),
143 .as_chunks::<4>()
144 .0
145 .iter()
146 .map(|id| u32::from_le_bytes(*id) >> 8),
145147 );
146148 }
147149 }
......@@ -394,7 +396,9 @@ pub(crate) fn replacement(id: ExGuid, object: &crate::Object<'_>) -> Result<Prop
394396 let text = |bytes: &[u8]| {
395397 String::from_utf16(
396398 &bytes
397 .chunks_exact(2)
399 .as_chunks::<2>()
400 .0
401 .iter()
398402 .map(|pair| u16::from_le_bytes([pair[0], pair[1]]))
399403 .collect::<Vec<_>>(),
400404 )
......@@ -968,8 +972,8 @@ impl<'a> LiveRevision<'a> {
968972 compact_ids,
969973 } = property.value
970974 {
971 for bytes in compact_ids.chunks_exact(4) {
972 let raw = u32::from_le_bytes(bytes.try_into().unwrap());
975 for bytes in compact_ids.as_chunks::<4>().0 {
976 let raw = u32::from_le_bytes(*bytes);
973977 if let Some((_, existing)) = targets.iter().find(|(id, _)| *id == raw) {
974978 let offset = bytes.as_ptr().addr() - object.bytes.as_ptr().addr();
975979 remapped.push((offset, *existing));
......@@ -1167,11 +1171,7 @@ fn moved_references(
11671171 compact_ids,
11681172 } = property.value
11691173 {
1170 ids.extend(
1171 compact_ids
1172 .chunks_exact(4)
1173 .map(|id| <[u8; 4]>::try_from(id).unwrap()),
1174 );
1174 ids.extend(compact_ids.as_chunks::<4>().0.iter().copied());
11751175 }
11761176 }
11771177 Ok(ids)
......@@ -1962,8 +1962,10 @@ impl Appending {
19621962 if let Value::References { compact_ids, .. } = property.value {
19631963 let offset =
19641964 compact_ids.as_ptr().addr() - bytes.as_ptr().addr();
1965 for (i, value) in compact_ids.chunks_exact(4).enumerate() {
1966 let value = u32::from_le_bytes(value.try_into().unwrap());
1965 for (i, value) in
1966 compact_ids.as_chunks::<4>().0.iter().enumerate()
1967 {
1968 let value = u32::from_le_bytes(*value);
19671969 let target = ExGuid {
19681970 guid: object.global_ids[&(value >> 8)],
19691971 n: value & 255,
......@@ -2196,7 +2198,7 @@ impl Appending {
21962198 crc_used += 8;
21972199 transaction_crc(checksum, entry, file_type, crc_used == crc_capacity)
21982200 };
2199 for entry in entries.chunks_exact(8) {
2201 for entry in entries.as_chunks::<8>().0 {
22002202 checksum = advance_crc(checksum, entry);
22012203 }
22022204 // Past a counter carry, sentinels up to the ceiling follow the one that commits; the
crates/onestore/src/write/tests.rs+2-2
......@@ -56,8 +56,8 @@ fn copying_reference_arrays_remaps_every_entry_in_each_stream() {
5656 panic!()
5757 };
5858 assert_eq!(compact_ids.len(), count as usize * 4);
59 for (i, compact) in compact_ids.chunks_exact(4).enumerate() {
60 let compact = u32::from_le_bytes(compact.try_into().unwrap());
59 for (i, compact) in compact_ids.as_chunks::<4>().0.iter().enumerate() {
60 let compact = u32::from_le_bytes(*compact);
6161 assert_eq!(compact & 255, i as u32);
6262 assert_eq!(target.global_ids[&(compact >> 8)], [(i % 3 + 1) as u8; 16]);
6363 }
crates/onestore/tests/page_removal.rs+6-5
......@@ -105,12 +105,13 @@ fn compare_copy(left: &Store<'_>, right: &Store<'_>, source: ExGuid, copied: ExG
105105 ) => {
106106 assert_eq!(stream, other_stream);
107107 assert_eq!(compact_ids.len(), other_ids.len());
108 for (a, b) in
109 compact_ids.chunks_exact(4).zip(other_ids.chunks_exact(4))
108 for (a, b) in compact_ids
109 .as_chunks::<4>()
110 .0
111 .iter()
112 .zip(other_ids.as_chunks::<4>().0.iter())
110113 {
111 let ids = [a, b].map(|bytes| {
112 u32::from_le_bytes(bytes.try_into().unwrap())
113 });
114 let ids = [a, b].map(|bytes| u32::from_le_bytes(*bytes));
114115 let [a, b] = [0, 1].map(|side| ExGuid {
115116 guid: objects[side].global_ids[&(ids[side] >> 8)],
116117 n: ids[side] & 255,
crates/onestore/tests/properties.rs+3-1
......@@ -20,7 +20,9 @@ fn native_property_chunks_preserve_unicode_and_ascii_text() {
2020 if property.id == 0x1c001c22 {
2121 let text = String::from_utf16(
2222 &data
23 .chunks_exact(2)
23 .as_chunks::<2>()
24 .0
25 .iter()
2426 .map(|pair| u16::from_le_bytes([pair[0], pair[1]]))
2527 .collect::<Vec<_>>(),
2628 )
crates/onestore/tests/revisions.rs+3-1
......@@ -170,7 +170,9 @@ fn active_revision_contains_current_text_and_exact_attachment_bytes() {
170170 };
171171 let text = String::from_utf16(
172172 &data
173 .chunks_exact(2)
173 .as_chunks::<2>()
174 .0
175 .iter()
174176 .map(|pair| u16::from_le_bytes([pair[0], pair[1]]))
175177 .collect::<Vec<_>>(),
176178 )
crates/onestore/tests/support/metadata.rs+3-3
......@@ -93,10 +93,10 @@ pub fn check(before: &ResolvedRevision<'_>, after: &ResolvedRevision<'_>, name:
9393 assert_eq!(old_fields.sets, new.sets);
9494 for field in old_fields.sets.iter().flatten() {
9595 if let Value::References { compact_ids, .. } = field.value {
96 let ids = compact_ids.chunks_exact(4);
97 assert!(ids.remainder().is_empty());
96 let (ids, remainder) = compact_ids.as_chunks::<4>();
97 assert!(remainder.is_empty());
9898 for compact in ids {
99 let entry = u32::from_le_bytes(compact.try_into().unwrap()) >> 8;
99 let entry = u32::from_le_bytes(*compact) >> 8;
100100 assert_eq!(
101101 metadata.global_ids.get(&entry),
102102 Some(&old.global_ids[&entry])
crates/onestore/tests/support/page_schedule.rs+1-1
......@@ -43,7 +43,7 @@ pub fn run(input: &[u8]) {
4343 }
4444 let mut persisted = source.to_vec();
4545 let mut caches = std::array::from_fn::<_, 12, _>(|_| source.to_vec());
46 for step in input.chunks_exact(8).take(24) {
46 for step in input.as_chunks::<8>().0.iter().take(24) {
4747 let actor = usize::from(step[0]) % caches.len();
4848 if step[1] % 3 == 0 {
4949 caches[actor].clone_from(&persisted);
crates/onestore/tests/support/tree_model.rs+1-1
......@@ -80,7 +80,7 @@ pub fn run(input: &[u8]) {
8080 };
8181 let mut persisted = source.to_vec();
8282 let mut clients = vec![persisted.clone(); 12];
83 for step in input.chunks_exact(10).take(36) {
83 for step in input.as_chunks::<10>().0.iter().take(36) {
8484 let client = usize::from(step[0]) % clients.len();
8585 if step[1] & 1 != 0 {
8686 clients[client] = persisted.clone();
crates/relay/src/server.rs+2-5
......@@ -543,11 +543,8 @@ impl Relay {
543543 else {
544544 return false;
545545 };
546 let named = named.chunks_exact(SLOT);
547 (
548 Some(named.map(|slot| u32::from_be_bytes(slot.try_into().unwrap()))),
549 payload,
550 )
546 let named = named.as_chunks::<SLOT>().0.iter();
547 (Some(named.map(|slot| u32::from_be_bytes(*slot))), payload)
551548 }
552549 _ => (None, rest),
553550 };
crates/snowbound/src/linux.rs+3-1
......@@ -944,7 +944,9 @@ pub fn symbolize(offsets: impl Iterator<Item = OsString>) -> Result<(), Box<dyn
944944 let strings = sections[field(table, 40, 4)];
945945 let strings = read(field(strings, 24, 8), field(strings, 32, 8))?;
946946 let mut ranges: Vec<(usize, usize, &[u8])> = symbols
947 .chunks_exact(24)
947 .as_chunks::<24>()
948 .0
949 .iter()
948950 .filter(|symbol| symbol[4] & 15 == 2 && field(symbol, 16, 8) > 0)
949951 .map(|symbol| {
950952 let name = &strings[field(symbol, 0, 4)..];
crates/snowbound/src/paste.rs+1-1
......@@ -49,7 +49,7 @@ pub(crate) fn pixels(encoded: &[u8]) -> Result<([u32; 2], Vec<u8>), Box<dyn Erro
4949 let image = draw::RasterImage::decode(encoded, [u32::MAX; 2])
5050 .map_err(|error| format!("{error:?}"))?;
5151 let mut rgba = image.pixels().to_vec();
52 for pixel in rgba.chunks_exact_mut(4) {
52 for pixel in rgba.as_chunks_mut::<4>().0 {
5353 if pixel[3] != 255 {
5454 let scale = 255.0 / f32::from(pixel[3].max(1));
5555 let linear = draw::srgb(pixel[0], pixel[1], pixel[2]).map(|v| v * scale);
crates/snowbound/src/screenshot.rs+1-1
......@@ -142,7 +142,7 @@ fn window_frame(
142142 };
143143 let [width, height] = [info.width as f32, info.height as f32];
144144 let radius = platform::CORNER_RADIUS * scale;
145 for (index, pixel) in pixels.chunks_exact_mut(4).enumerate() {
145 for (index, pixel) in pixels.as_chunks_mut::<4>().0.iter_mut().enumerate() {
146146 let x = (index as u32 % info.width) as f32 + 0.5;
147147 let y = (index as u32 / info.width) as f32 + 0.5;
148148 for ([cx, cy], (fill, rim)) in lights.into_iter().zip(LIGHTS) {
crates/snowbound/src/screenshot/snow_leopard.rs+4-4
......@@ -194,12 +194,12 @@ fn window(
194194 })
195195 .collect();
196196 for (y, row) in content.chunks_exact(width * 4).enumerate() {
197 for (x, pixel) in row.chunks_exact(4).enumerate() {
197 for (x, pixel) in row.as_chunks::<4>().0.iter().enumerate() {
198198 composite(&mut pixels[(y + TITLE_LINE) * width + x], pixel);
199199 }
200200 }
201201 for (y, row) in bar.chunks_exact(width * 4).enumerate() {
202 for (x, pixel) in row.chunks_exact(4).enumerate() {
202 for (x, pixel) in row.as_chunks::<4>().0.iter().enumerate() {
203203 composite(&mut pixels[y * width + x], pixel);
204204 }
205205 }
......@@ -209,9 +209,9 @@ fn window(
209209 let mut buttons = vec![0; reader.output_buffer_size().ok_or("Buttons too large")?];
210210 let info = reader.next_frame(&mut buttons)?;
211211 for (y, row) in buttons.chunks_exact(info.width as usize * 4).enumerate() {
212 for (x, pixel) in row.chunks_exact(4).enumerate() {
212 for (x, pixel) in row.as_chunks::<4>().0.iter().enumerate() {
213213 let at = (4 + y) * width + 8 + 21 * (x / 14) + x % 14;
214 over(&mut pixels[at], pixel.try_into()?);
214 over(&mut pixels[at], *pixel);
215215 }
216216 }
217217 // AppKit rounds the top corners by about 4.5 pixels, a textured window's bottom ones by
crates/snowbound/src/surface.rs+1-1
......@@ -299,7 +299,7 @@ impl Surface {
299299 pixels.extend_from_slice(&line[..size[0] as usize * 4]);
300300 }
301301 if bgra {
302 for pixel in pixels.chunks_exact_mut(4) {
302 for pixel in pixels.as_chunks_mut::<4>().0 {
303303 pixel.swap(0, 2);
304304 }
305305 }
crates/snowbound/src/watch.rs+3-1
......@@ -641,7 +641,9 @@ mod platform {
641641 let start = at + std::mem::offset_of!(FILE_NOTIFY_INFORMATION, FileName);
642642 let end = (start + entry.FileNameLength as usize).min(bytes.len());
643643 let name: Vec<u16> = bytes[start..end]
644 .chunks_exact(2)
644 .as_chunks::<2>()
645 .0
646 .iter()
645647 .map(|pair| u16::from_le_bytes([pair[0], pair[1]]))
646648 .collect();
647649 paths.push(root.join(String::from_utf16_lossy(&name)));
crates/snowbound/src/windows.rs+1-1
......@@ -1138,7 +1138,7 @@ impl Clipboard {
11381138 let formats = if let Some(picture) = &copied.picture {
11391139 let (size, mut rgba) =
11401140 crate::paste::pixels(picture).map_err(|_| "The picture couldn't be decoded")?;
1141 for pixel in rgba.chunks_exact_mut(4) {
1141 for pixel in rgba.as_chunks_mut::<4>().0 {
11421142 pixel.swap(0, 2);
11431143 }
11441144 let header = [