Skip to content

Commit 4a9573c

Browse files
committed
Improve UX for manual use of helper functions
This makes generic parameter order consistent across all helpers and orders them so the parameters most likely to need explicit overrides are put at the start of the parameter list instead of the end.
1 parent 1b7fc34 commit 4a9573c

File tree

2 files changed

+48
-43
lines changed

2 files changed

+48
-43
lines changed

binrw/src/helpers.rs

+38-36
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ use core::iter::from_fn;
2828
/// # let x: NullTerminated = x.read_be().unwrap();
2929
/// # assert_eq!(x.data, &[1, 2, 3, 4, 0]);
3030
/// ```
31-
pub fn until<Reader, T, CondFn, Arg, Ret>(
31+
pub fn until<Ret, T, Arg, CondFn, Reader>(
3232
cond: CondFn,
3333
) -> impl Fn(&mut Reader, Endian, Arg) -> BinResult<Ret>
3434
where
35+
Ret: FromIterator<T>,
3536
T: for<'a> BinRead<Args<'a> = Arg>,
36-
Reader: Read + Seek,
37-
CondFn: Fn(&T) -> bool,
3837
Arg: Clone,
39-
Ret: FromIterator<T>,
38+
CondFn: Fn(&T) -> bool,
39+
Reader: Read + Seek,
4040
{
4141
until_with(cond, T::read_options)
4242
}
@@ -67,16 +67,16 @@ where
6767
/// # let x: NullTerminated = x.read_be().unwrap();
6868
/// # assert_eq!(x.data, &[[1, 2], [3, 4], [0, 0]]);
6969
/// ```
70-
pub fn until_with<Reader, T, CondFn, Arg, ReadFn, Ret>(
70+
pub fn until_with<Ret, T, Arg, CondFn, ReadFn, Reader>(
7171
cond: CondFn,
7272
read: ReadFn,
7373
) -> impl Fn(&mut Reader, Endian, Arg) -> BinResult<Ret>
7474
where
75-
Reader: Read + Seek,
76-
CondFn: Fn(&T) -> bool,
75+
Ret: FromIterator<T>,
7776
Arg: Clone,
77+
CondFn: Fn(&T) -> bool,
7878
ReadFn: Fn(&mut Reader, Endian, Arg) -> BinResult<T>,
79-
Ret: FromIterator<T>,
79+
Reader: Read + Seek,
8080
{
8181
move |reader, endian, args| {
8282
let mut last = false;
@@ -120,15 +120,15 @@ where
120120
/// # let x: NullTerminated = x.read_be().unwrap();
121121
/// # assert_eq!(x.data, &[1, 2, 3, 4]);
122122
/// ```
123-
pub fn until_exclusive<Reader, T, CondFn, Arg, Ret>(
123+
pub fn until_exclusive<Ret, T, Arg, CondFn, Reader>(
124124
cond: CondFn,
125125
) -> impl Fn(&mut Reader, Endian, Arg) -> BinResult<Ret>
126126
where
127+
Ret: FromIterator<T>,
127128
T: for<'a> BinRead<Args<'a> = Arg>,
128-
Reader: Read + Seek,
129-
CondFn: Fn(&T) -> bool,
130129
Arg: Clone,
131-
Ret: FromIterator<T>,
130+
CondFn: Fn(&T) -> bool,
131+
Reader: Read + Seek,
132132
{
133133
until_exclusive_with(cond, T::read_options)
134134
}
@@ -159,16 +159,16 @@ where
159159
/// # let x: NullTerminated = x.read_be().unwrap();
160160
/// # assert_eq!(x.data, &[[1, 2], [3, 4]]);
161161
/// ```
162-
pub fn until_exclusive_with<Reader, T, CondFn, Arg, ReadFn, Ret>(
162+
pub fn until_exclusive_with<Ret, T, Arg, CondFn, ReadFn, Reader>(
163163
cond: CondFn,
164164
read: ReadFn,
165165
) -> impl Fn(&mut Reader, Endian, Arg) -> BinResult<Ret>
166166
where
167-
Reader: Read + Seek,
168-
CondFn: Fn(&T) -> bool,
167+
Ret: FromIterator<T>,
169168
Arg: Clone,
169+
CondFn: Fn(&T) -> bool,
170170
ReadFn: Fn(&mut Reader, Endian, Arg) -> BinResult<T>,
171-
Ret: FromIterator<T>,
171+
Reader: Read + Seek,
172172
{
173173
move |reader, endian, args| {
174174
from_fn(|| match read(reader, endian, args.clone()) {
@@ -211,16 +211,16 @@ where
211211
/// # let x: EntireFile = x.read_be().unwrap();
212212
/// # assert_eq!(x.data, &[1, 2, 3, 4]);
213213
/// ```
214-
pub fn until_eof<Reader, T, Arg, Ret>(
214+
pub fn until_eof<Ret, T, Arg, Reader>(
215215
reader: &mut Reader,
216216
endian: Endian,
217217
args: Arg,
218218
) -> BinResult<Ret>
219219
where
220+
Ret: FromIterator<T>,
220221
T: for<'a> BinRead<Args<'a> = Arg>,
221-
Reader: Read + Seek,
222222
Arg: Clone,
223-
Ret: FromIterator<T>,
223+
Reader: Read + Seek,
224224
{
225225
until_eof_with(T::read_options)(reader, endian, args)
226226
}
@@ -256,14 +256,14 @@ where
256256
/// # let x: EntireFile = x.read_be().unwrap();
257257
/// # assert_eq!(x.data, &[[1, 2], [3, 4]]);
258258
/// ```
259-
pub fn until_eof_with<Reader, T, Arg, ReadFn, Ret>(
259+
pub fn until_eof_with<Ret, T, Arg, ReadFn, Reader>(
260260
read: ReadFn,
261261
) -> impl Fn(&mut Reader, Endian, Arg) -> BinResult<Ret>
262262
where
263-
Reader: Read + Seek,
263+
Ret: FromIterator<T>,
264264
Arg: Clone,
265265
ReadFn: Fn(&mut Reader, Endian, Arg) -> BinResult<T>,
266-
Ret: FromIterator<T>,
266+
Reader: Read + Seek,
267267
{
268268
move |reader, endian, args| {
269269
from_fn(|| match read(reader, endian, args.clone()) {
@@ -350,14 +350,14 @@ where
350350
/// # let x = Object::read(&mut x).unwrap();
351351
/// # assert_eq!(x.segments, &[vec![3], vec![4, 5]]);
352352
/// ```
353-
pub fn args_iter<'a, R, T, Arg, Ret, It>(
353+
pub fn args_iter<'a, Ret, T, Arg, It, Reader>(
354354
it: It,
355-
) -> impl FnOnce(&mut R, Endian, ()) -> BinResult<Ret>
355+
) -> impl FnOnce(&mut Reader, Endian, ()) -> BinResult<Ret>
356356
where
357-
T: BinRead<Args<'a> = Arg>,
358-
R: Read + Seek,
359357
Ret: FromIterator<T>,
358+
T: BinRead<Args<'a> = Arg>,
360359
It: IntoIterator<Item = Arg>,
360+
Reader: Read + Seek,
361361
{
362362
// For an unknown reason (possibly related to the note in the compiler error
363363
// that says “due to current limitations in the borrow checker”), trying to
@@ -405,15 +405,15 @@ where
405405
/// # let x = Object::read(&mut x).unwrap();
406406
/// # assert_eq!(x.segments, &[vec![3], vec![4, 5]]);
407407
/// ```
408-
pub fn args_iter_with<Reader, T, Arg, Ret, It, ReadFn>(
408+
pub fn args_iter_with<Ret, T, Arg, It, ReadFn, Reader>(
409409
it: It,
410410
read: ReadFn,
411411
) -> impl FnOnce(&mut Reader, Endian, ()) -> BinResult<Ret>
412412
where
413-
Reader: Read + Seek,
414413
Ret: FromIterator<T>,
415414
It: IntoIterator<Item = Arg>,
416415
ReadFn: Fn(&mut Reader, Endian, Arg) -> BinResult<T>,
416+
Reader: Read + Seek,
417417
{
418418
move |reader, options, ()| {
419419
it.into_iter()
@@ -445,12 +445,14 @@ where
445445
/// # let x: CountBytes = x.read_be().unwrap();
446446
/// # assert_eq!(x.data, &[1, 2, 3]);
447447
/// ```
448-
pub fn count<'a, R, T, Arg, Ret>(n: usize) -> impl Fn(&mut R, Endian, Arg) -> BinResult<Ret>
448+
pub fn count<'a, Ret, T, Arg, Reader>(
449+
n: usize,
450+
) -> impl Fn(&mut Reader, Endian, Arg) -> BinResult<Ret>
449451
where
452+
Ret: FromIterator<T> + 'static,
450453
T: BinRead<Args<'a> = Arg>,
451-
R: Read + Seek,
452454
Arg: Clone,
453-
Ret: FromIterator<T> + 'static,
455+
Reader: Read + Seek,
454456
{
455457
move |reader, endian, args| {
456458
let mut container = core::iter::empty::<T>().collect::<Ret>();
@@ -510,15 +512,15 @@ where
510512
/// # let x: CountBytes = x.read_be().unwrap();
511513
/// # assert_eq!(x.data, &[[1, 2], [3, 4]]);
512514
/// ```
513-
pub fn count_with<R, T, Arg, ReadFn, Ret>(
515+
pub fn count_with<Ret, T, Arg, ReadFn, Reader>(
514516
n: usize,
515517
read: ReadFn,
516-
) -> impl Fn(&mut R, Endian, Arg) -> BinResult<Ret>
518+
) -> impl Fn(&mut Reader, Endian, Arg) -> BinResult<Ret>
517519
where
518-
R: Read + Seek,
519-
Arg: Clone,
520-
ReadFn: Fn(&mut R, Endian, Arg) -> BinResult<T>,
521520
Ret: FromIterator<T> + 'static,
521+
Arg: Clone,
522+
ReadFn: Fn(&mut Reader, Endian, Arg) -> BinResult<T>,
523+
Reader: Read + Seek,
522524
{
523525
move |reader, endian, args| {
524526
core::iter::repeat_with(|| read(reader, endian, args.clone()))

binrw/tests/binread_impls.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,14 @@ fn vec_u8() {
114114

115115
#[test]
116116
fn count_with_correctness() {
117-
let read = binrw::helpers::count_with(2, binrw::helpers::read_u24);
118-
let _: Vec<u32> = read(
119-
&mut Cursor::new(&[0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF]),
120-
binrw::Endian::Little,
121-
(),
122-
)
123-
.expect("more than 3 bytes per u24 should not be required");
117+
let read = binrw::helpers::count_with::<Vec<u32>, _, _, _, _>(2, binrw::helpers::read_u24);
118+
assert_eq!(
119+
read(
120+
&mut Cursor::new(&[0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF]),
121+
binrw::Endian::Little,
122+
(),
123+
)
124+
.expect("Vec fake-specialisation should not ignore reader function"),
125+
vec![0, 0xffffff]
126+
);
124127
}

0 commit comments

Comments
 (0)